//-------------------------------------------------------------------------- //初期化処理 private void Start() { #pragma warning disable 0219 string Tag = "[" + this.GetType().Name + ":" + System.Reflection.MethodBase.GetCurrentMethod(); //クラス名とメソッド名を自動取得 #pragma warning restore 0219 Debug.Log(Tag + "Begin"); var openVRError = EVRInitError.None; var overlayError = EVROverlayError.None; error = false; if (!OpenVR.IsHmdPresent()) { this.enabled = false; } //フレームレートを90fpsにする。(しないと無限に早くなることがある) Application.targetFrameRate = 90; Debug.Log(Tag + "Set Frame Rate 90"); //OpenVRの初期化 openvr = OpenVR.Init(ref openVRError, EVRApplicationType.VRApplication_Overlay); if (openVRError != EVRInitError.None) { Debug.LogError(Tag + "OpenVRの初期化に失敗." + openVRError.ToString()); ProcessError(); return; } //オーバーレイ機能の初期化 overlay = OpenVR.Overlay; overlayError = overlay.CreateOverlay(OverlayKeyName, OverlayFriendlyName, ref overlayHandle); if (overlayError != EVROverlayError.None) { Debug.LogError(Tag + "Overlayの初期化に失敗. " + overlayError.ToString()); ProcessError(); return; } //オーバーレイに渡すテクスチャ種類の設定 var OverlayTextureBounds = new VRTextureBounds_t(); var isOpenGL = SystemInfo.graphicsDeviceVersion.Contains("OpenGL"); if (isOpenGL) { //pGLuintTexture overlayTexture.eType = ETextureType.OpenGL; //上下反転しない OverlayTextureBounds.uMin = 1; OverlayTextureBounds.vMin = 0; OverlayTextureBounds.uMax = 1; OverlayTextureBounds.vMax = 0; overlay.SetOverlayTextureBounds(overlayHandle, ref OverlayTextureBounds); } else { //pTexture overlayTexture.eType = ETextureType.DirectX; //上下反転する OverlayTextureBounds.uMin = 0; OverlayTextureBounds.vMin = 1; OverlayTextureBounds.uMax = 1; OverlayTextureBounds.vMax = 0; overlay.SetOverlayTextureBounds(overlayHandle, ref OverlayTextureBounds); } //-------- showDevices(); Debug.Log(Tag + "初期化完了しました"); }
void Update() { if (Time.frameCount == prevFrameCount) { return; } prevFrameCount = Time.frameCount; if (videostream.handle == 0) { return; } var vr = SteamVR.instance; if (vr == null) { return; } var trackedCamera = OpenVR.TrackedCamera; if (trackedCamera == null) { return; } var nativeTex = System.IntPtr.Zero; var deviceTexture = (_texture != null) ? _texture : new Texture2D(2, 2); var headerSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(header.GetType()); if (vr.graphicsAPI == EGraphicsAPIConvention.API_OpenGL) { if (glTextureId != 0) { trackedCamera.ReleaseVideoStreamTextureGL(videostream.handle, glTextureId); } if (trackedCamera.GetVideoStreamTextureGL(videostream.handle, frameType, ref glTextureId, ref header, headerSize) != EVRTrackedCameraError.None) { return; } nativeTex = (System.IntPtr)glTextureId; } else { if (trackedCamera.GetVideoStreamTextureD3D11(videostream.handle, frameType, deviceTexture.GetNativeTexturePtr(), ref nativeTex, ref header, headerSize) != EVRTrackedCameraError.None) { return; } } if (_texture == null) { _texture = Texture2D.CreateExternalTexture((int)header.nWidth, (int)header.nHeight, TextureFormat.RGBA32, false, false, nativeTex); uint width = 0, height = 0; var frameBounds = new VRTextureBounds_t(); if (trackedCamera.GetVideoStreamTextureSize(deviceIndex, frameType, ref frameBounds, ref width, ref height) == EVRTrackedCameraError.None) { // Account for textures being upside-down in Unity. frameBounds.vMin = 1.0f - frameBounds.vMin; frameBounds.vMax = 1.0f - frameBounds.vMax; this.frameBounds = frameBounds; } } else { _texture.UpdateExternalTexture(nativeTex); } }
public static Mesh CreateHiddenAreaMesh(HiddenAreaMesh_t src, VRTextureBounds_t bounds) { if (src.unTriangleCount == 0) { return(null); } var data = new float[src.unTriangleCount * 3 * 2]; //HmdVector2_t Marshal.Copy(src.pVertexData, data, 0, data.Length); var vertices = new Vector3[src.unTriangleCount * 3 + 12]; var indices = new int[src.unTriangleCount * 3 + 24]; var x0 = 2.0f * bounds.uMin - 1.0f; var x1 = 2.0f * bounds.uMax - 1.0f; var y0 = 2.0f * bounds.vMin - 1.0f; var y1 = 2.0f * bounds.vMax - 1.0f; for (int i = 0, j = 0; i < src.unTriangleCount * 3; i++) { var x = Lerp(x0, x1, data[j++]); var y = Lerp(y0, y1, data[j++]); vertices[i] = new Vector3(x, y, 0.0f); indices[i] = i; } // Add border var offset = (int)src.unTriangleCount * 3; var iVert = offset; vertices[iVert++] = new Vector3(-1, -1, 0); vertices[iVert++] = new Vector3(x0, -1, 0); vertices[iVert++] = new Vector3(-1, 1, 0); vertices[iVert++] = new Vector3(x0, 1, 0); vertices[iVert++] = new Vector3(x1, -1, 0); vertices[iVert++] = new Vector3(1, -1, 0); vertices[iVert++] = new Vector3(x1, 1, 0); vertices[iVert++] = new Vector3(1, 1, 0); vertices[iVert++] = new Vector3(x0, y0, 0); vertices[iVert++] = new Vector3(x1, y0, 0); vertices[iVert++] = new Vector3(x0, y1, 0); vertices[iVert++] = new Vector3(x1, y1, 0); var iTri = offset; indices[iTri++] = offset + 0; indices[iTri++] = offset + 1; indices[iTri++] = offset + 2; indices[iTri++] = offset + 2; indices[iTri++] = offset + 1; indices[iTri++] = offset + 3; indices[iTri++] = offset + 4; indices[iTri++] = offset + 5; indices[iTri++] = offset + 6; indices[iTri++] = offset + 6; indices[iTri++] = offset + 5; indices[iTri++] = offset + 7; indices[iTri++] = offset + 1; indices[iTri++] = offset + 4; indices[iTri++] = offset + 8; indices[iTri++] = offset + 8; indices[iTri++] = offset + 4; indices[iTri++] = offset + 9; indices[iTri++] = offset + 10; indices[iTri++] = offset + 11; indices[iTri++] = offset + 3; indices[iTri++] = offset + 3; indices[iTri++] = offset + 11; indices[iTri++] = offset + 6; var mesh = new Mesh(); mesh.vertices = vertices; mesh.triangles = indices; mesh.bounds = new Bounds(Vector3.zero, new Vector3(float.MaxValue, float.MaxValue, float.MaxValue)); // Prevent frustum culling from culling this mesh return(mesh); }
public void UpdateOverlay(SteamVR vr) { if (texture != null) { var error = vr.overlay.ShowOverlay(handle); if (error == VROverlayError.InvalidHandle || error == VROverlayError.UnknownOverlay) { if (vr.overlay.FindOverlay(key, ref handle) != VROverlayError.None) { return; } } vr.overlay.SetOverlayTexture(handle, vr.graphicsAPI, texture.GetNativeTexturePtr()); vr.overlay.SetOverlayAlpha(handle, alpha); vr.overlay.SetOverlayGamma(handle, gamma); vr.overlay.SetOverlayWidthInMeters(handle, scale); vr.overlay.SetOverlayAutoCurveDistanceRangeInMeters(handle, curvedRange.x, curvedRange.y); var textureBounds = new VRTextureBounds_t(); textureBounds.uMin = (0 + uvOffset.x) * uvOffset.z; textureBounds.vMin = (1 + uvOffset.y) * uvOffset.w; textureBounds.uMax = (1 + uvOffset.x) * uvOffset.z; textureBounds.vMax = (0 + uvOffset.y) * uvOffset.w; vr.overlay.SetOverlayTextureBounds(handle, ref textureBounds); var vecMouseScale = new HmdVector2_t(); vecMouseScale.v = new float[] { mouseScale.x, mouseScale.y }; vr.overlay.SetOverlayMouseScale(handle, ref vecMouseScale); var vrcam = SteamVR_Render.Top(); if (vrcam != null && vrcam.origin != null) { var offset = new SteamVR_Utils.RigidTransform(vrcam.origin, transform); offset.pos.x /= vrcam.origin.localScale.x; offset.pos.y /= vrcam.origin.localScale.y; offset.pos.z /= vrcam.origin.localScale.z; offset.pos.z += distance; var t = offset.ToHmdMatrix34(); vr.overlay.SetOverlayTransformAbsolute(handle, SteamVR_Render.instance.trackingSpace, ref t); } vr.overlay.SetOverlayInputMethod(handle, inputMethod); if (curved || antialias) { highquality = true; } if (highquality) { vr.overlay.SetHighQualityOverlay(handle); vr.overlay.SetOverlayFlag(handle, VROverlayFlags.Curved, curved); vr.overlay.SetOverlayFlag(handle, VROverlayFlags.RGSS4X, antialias); } else if (vr.overlay.GetHighQualityOverlay() == handle) { vr.overlay.SetHighQualityOverlay(OpenVR.k_ulOverlayHandleInvalid); } } else { vr.overlay.HideOverlay(handle); } }
/// <summary> /// Update the Overlay /// </summary> private void UpdateOverlay() { var overlay = OpenVR.Overlay; if (overlay == null) { return; } if (OverlayTexture != null) // Texture set { var error = overlay.ShowOverlay(_overlayHandle); // Show Overlay if (error == EVROverlayError.InvalidHandle || error == EVROverlayError.UnknownOverlay) // Overlay handle invalid { if (overlay.FindOverlay(Key + gameObject.GetInstanceID(), ref _overlayHandle) != EVROverlayError.None) // Attempt to grab handle by name { return; } } // Setup a Native texture var tex = new Texture_t { handle = OverlayTexture.GetNativeTexturePtr(), eType = SteamVR.instance.graphicsAPI, eColorSpace = EColorSpace.Auto }; overlay.SetOverlayColor(_overlayHandle, 1f, 1f, 1f); // Assign Overlay Color overlay.SetOverlayTexture(_overlayHandle, ref tex); // Assign Overlay Texture overlay.SetOverlayAlpha(_overlayHandle, 1f); // Assign Overlay Alpha overlay.SetOverlayWidthInMeters(_overlayHandle, Scale); // Assign Overlay Scale (height is automatic to match texture aspect) overlay.SetOverlayAutoCurveDistanceRangeInMeters(_overlayHandle, CurvedRange.x, CurvedRange.y); // Setup Texture bounds var textureBounds = new VRTextureBounds_t { uMin = (0 + UvOffset.x) * UvOffset.z, vMin = (1 + UvOffset.y) * UvOffset.w, uMax = (1 + UvOffset.x) * UvOffset.z, vMax = (0 + UvOffset.y) * UvOffset.w }; overlay.SetOverlayTextureBounds(_overlayHandle, ref textureBounds); var vecMouseScale = new HmdVector2_t { v0 = 1f, v1 = (float)OverlayTexture.height / (float)OverlayTexture.width }; overlay.SetOverlayMouseScale(_overlayHandle, ref vecMouseScale); // Attach Overlay to relative position if (AnchorDeviceId != OpenVR.k_unTrackedDeviceIndexInvalid) // Attach to some device (like a controller) { var t = GetOverlayPosition(); overlay.SetOverlayTransformTrackedDeviceRelative(_overlayHandle, AnchorDeviceId, ref t); } else // Attach to position in world { var t = GetOverlayPosition(); overlay.SetOverlayTransformAbsolute(_overlayHandle, SteamVR_Render.instance.trackingSpace, ref t); } overlay.SetOverlayInputMethod(_overlayHandle, VROverlayInputMethod.None); } else // Texture not set, hide overlay { overlay.HideOverlay(_overlayHandle); } }
public void UpdateOverlay() { CVROverlay overlay = OpenVR.Overlay; if (overlay == null) { return; } if (this.texture != null) { EVROverlayError evroverlayError = overlay.ShowOverlay(this.handle); if ((evroverlayError == EVROverlayError.InvalidHandle || evroverlayError == EVROverlayError.UnknownOverlay) && overlay.FindOverlay(SteamVR_Overlay.key, ref this.handle) != EVROverlayError.None) { return; } Texture_t texture_t = default(Texture_t); texture_t.handle = this.texture.GetNativeTexturePtr(); texture_t.eType = SteamVR.instance.textureType; texture_t.eColorSpace = EColorSpace.Auto; overlay.SetOverlayTexture(this.handle, ref texture_t); overlay.SetOverlayAlpha(this.handle, this.alpha); overlay.SetOverlayWidthInMeters(this.handle, this.scale); overlay.SetOverlayAutoCurveDistanceRangeInMeters(this.handle, this.curvedRange.x, this.curvedRange.y); VRTextureBounds_t vrtextureBounds_t = default(VRTextureBounds_t); vrtextureBounds_t.uMin = this.uvOffset.x * this.uvOffset.z; vrtextureBounds_t.vMin = (1f + this.uvOffset.y) * this.uvOffset.w; vrtextureBounds_t.uMax = (1f + this.uvOffset.x) * this.uvOffset.z; vrtextureBounds_t.vMax = this.uvOffset.y * this.uvOffset.w; overlay.SetOverlayTextureBounds(this.handle, ref vrtextureBounds_t); HmdVector2_t hmdVector2_t = default(HmdVector2_t); hmdVector2_t.v0 = this.mouseScale.x; hmdVector2_t.v1 = this.mouseScale.y; overlay.SetOverlayMouseScale(this.handle, ref hmdVector2_t); SteamVR_Camera steamVR_Camera = SteamVR_Render.Top(); if (steamVR_Camera != null && steamVR_Camera.origin != null) { SteamVR_Utils.RigidTransform rigidTransform = new SteamVR_Utils.RigidTransform(steamVR_Camera.origin, base.transform); rigidTransform.pos.x = rigidTransform.pos.x / steamVR_Camera.origin.localScale.x; rigidTransform.pos.y = rigidTransform.pos.y / steamVR_Camera.origin.localScale.y; rigidTransform.pos.z = rigidTransform.pos.z / steamVR_Camera.origin.localScale.z; rigidTransform.pos.z = rigidTransform.pos.z + this.distance; HmdMatrix34_t hmdMatrix34_t = rigidTransform.ToHmdMatrix34(); overlay.SetOverlayTransformAbsolute(this.handle, SteamVR_Render.instance.trackingSpace, ref hmdMatrix34_t); } overlay.SetOverlayInputMethod(this.handle, this.inputMethod); if (this.curved || this.antialias) { this.highquality = true; } if (this.highquality) { overlay.SetHighQualityOverlay(this.handle); overlay.SetOverlayFlag(this.handle, VROverlayFlags.Curved, this.curved); overlay.SetOverlayFlag(this.handle, VROverlayFlags.RGSS4X, this.antialias); } else if (overlay.GetHighQualityOverlay() == this.handle) { overlay.SetHighQualityOverlay(0UL); } } else { overlay.HideOverlay(this.handle); } }
// Token: 0x06005FAF RID: 24495 RVA: 0x0021A4B0 File Offset: 0x002188B0 private void Update() { if (Time.frameCount == this.prevFrameCount) { return; } this.prevFrameCount = Time.frameCount; if (this.videostream.handle == 0UL) { return; } SteamVR instance = SteamVR.instance; if (instance == null) { return; } CVRTrackedCamera trackedCamera = OpenVR.TrackedCamera; if (trackedCamera == null) { return; } IntPtr nativeTex = IntPtr.Zero; Texture2D texture2D = (!(this._texture != null)) ? new Texture2D(2, 2) : this._texture; uint nFrameHeaderSize = (uint)Marshal.SizeOf(this.header.GetType()); if (instance.textureType == ETextureType.OpenGL) { if (this.glTextureId != 0u) { trackedCamera.ReleaseVideoStreamTextureGL(this.videostream.handle, this.glTextureId); } if (trackedCamera.GetVideoStreamTextureGL(this.videostream.handle, this.frameType, ref this.glTextureId, ref this.header, nFrameHeaderSize) != EVRTrackedCameraError.None) { return; } nativeTex = (IntPtr)((long)((ulong)this.glTextureId)); } else if (instance.textureType == ETextureType.DirectX && trackedCamera.GetVideoStreamTextureD3D11(this.videostream.handle, this.frameType, texture2D.GetNativeTexturePtr(), ref nativeTex, ref this.header, nFrameHeaderSize) != EVRTrackedCameraError.None) { return; } if (this._texture == null) { this._texture = Texture2D.CreateExternalTexture((int)this.header.nWidth, (int)this.header.nHeight, TextureFormat.RGBA32, false, false, nativeTex); uint num = 0u; uint num2 = 0u; VRTextureBounds_t frameBounds = default(VRTextureBounds_t); if (trackedCamera.GetVideoStreamTextureSize(this.deviceIndex, this.frameType, ref frameBounds, ref num, ref num2) == EVRTrackedCameraError.None) { frameBounds.vMin = 1f - frameBounds.vMin; frameBounds.vMax = 1f - frameBounds.vMax; this.frameBounds = frameBounds; } } else { this._texture.UpdateExternalTexture(nativeTex); } }
public abstract VRCompositorError Submit(Hmd_Eye eEye,GraphicsAPIConvention eTextureType,IntPtr pTexture,ref VRTextureBounds_t pBounds,VRSubmitFlags_t nSubmitFlags);
// Update is called once per frame void Update() { if (planeShowHide.GetState(handType_left)) { if (!isCamStarted) { StartCamera(); isCamStarted = true; } capturePlane.GetComponent <MeshRenderer>().enabled = true; } else { capturePlane.GetComponent <MeshRenderer>().enabled = false; if (isCamStarted) { isCamStarted = false; // StopCamera(); } } ButtonInteract(); if (captureImage.GetStateDown(handType_left) && isCamStarted) { processedTexture = new RenderTexture(cameraTexture.width, cameraTexture.height, 16, RenderTextureFormat.ARGB32); Graphics.Blit(cameraTexture, processedTexture); RenderTexture.active = processedTexture; virtualPhoto = new Texture2D(cameraTexture.width, cameraTexture.height, TextureFormat.RGB24, false); virtualPhoto.ReadPixels(new Rect(0, 0, cameraTexture.width, cameraTexture.height), 0, 0); virtualPhoto.Apply(); inputPlane.GetComponent <Renderer>().material.mainTexture = virtualPhoto; VRTextureBounds_t bounds = source.frameBounds; inputPlane.GetComponent <Renderer>().material.mainTextureOffset = new Vector2(bounds.uMin, bounds.vMin); float du = bounds.uMax - bounds.uMin; float dv = bounds.vMax - bounds.vMin; inputPlane.GetComponent <Renderer>().material.mainTextureScale = new Vector2(du, dv); Debug.Log(bounds.uMin + " | " + bounds.vMin + " | " + bounds.uMax + " | " + bounds.vMax + " | "); Debug.Log(du + " | " + dv); //Vector3 currScale = inputPlane.transform.localScale; //inputPlane.transform.localScale = new Vector3( currScale.x*((float)virtualPhoto.width / (float)virtualPhoto.height), currScale.y, currScale.z); if (modeSelected != -1) { isNewImage = true; isNewMode = true; } else { isNewImage = true; } // inputTexture.SetPixels(currCapture.GetPixels()); // inputTexture.Apply(); } }
public VRRenderer(SharpDX.Direct3D11.Device d3d11Device, SharpDX.Direct3D11.Device unityDevice, VRRig rig) { instance = this; this.rig = rig; device = d3d11Device; unityRenderer = unityDevice; bounds = new VRTextureBounds_t(); bounds.vMin = bounds.uMin = 0; bounds.vMax = bounds.uMax = 1; var w = rig.leftTexture.Description.Width; var h = rig.leftTexture.Description.Height; var description = new SharpDX.Direct3D11.Texture2DDescription() { Width = (int)w, Height = (int)h, MipLevels = 1, ArraySize = 1, SampleDescription = new SampleDescription() { Count = 1 }, BindFlags = SharpDX.Direct3D11.BindFlags.ShaderResource | SharpDX.Direct3D11.BindFlags.RenderTarget, CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None, Format = Format.R8G8B8A8_UNorm, OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.Shared, Usage = SharpDX.Direct3D11.ResourceUsage.Default }; System.Diagnostics.Trace.WriteLine("Creating D3D11 Textures"); leftVRTexture = new SharpDX.Direct3D11.Texture2D(d3d11Device, description); rightVRTexture = new SharpDX.Direct3D11.Texture2D(d3d11Device, description); leftEye = new Texture_t() { eColorSpace = EColorSpace.Gamma, eType = ETextureType.DirectX, handle = leftVRTexture.NativePointer }; rightEye = new Texture_t() { eColorSpace = EColorSpace.Gamma, eType = ETextureType.DirectX, handle = rightVRTexture.NativePointer }; var sharedHandleLeft = leftVRTexture.QueryInterface <Resource>().SharedHandle; var sharedHandleRight = rightVRTexture.QueryInterface <Resource>().SharedHandle; leftHandle = unityRenderer.OpenSharedResource <SharpDX.Direct3D11.Texture2D>(sharedHandleLeft); rightHandle = unityRenderer.OpenSharedResource <SharpDX.Direct3D11.Texture2D>(sharedHandleRight); var viewDesc = new SharpDX.Direct3D11.ShaderResourceViewDescription() { Format = Format.R8G8B8A8_UNorm, Dimension = SharpDX.Direct3D.ShaderResourceViewDimension.Texture2D, Texture2D = new SharpDX.Direct3D11.ShaderResourceViewDescription.Texture2DResource() { MipLevels = 1, MostDetailedMip = 0 } }; var leftView = new SharpDX.Direct3D11.ShaderResourceView(unityDevice, leftHandle, viewDesc); var rightView = new SharpDX.Direct3D11.ShaderResourceView(unityDevice, rightHandle, viewDesc); leftUnityTexture = Texture2D.CreateExternalTexture(w, h, TextureFormat.ARGB32, false, false, leftView.NativePointer); rightUnityTexture = Texture2D.CreateExternalTexture(w, h, TextureFormat.ARGB32, false, false, rightView.NativePointer); }
public void UpdateOverlay(Transform origin, ETrackingUniverseOrigin trackingSpace) { var overlay = OpenVR.Overlay; if (overlay == null) { return; } var error = EVROverlayError.None; error = overlay.ShowOverlay(handle); if (error == EVROverlayError.InvalidHandle || error == EVROverlayError.UnknownOverlay) { if (overlay.FindOverlay(overlayKey, ref handle) != EVROverlayError.None) { CreateOverlay(); return; } } while (PollNextEvent(ref pEvent)) { EventHandler(ref pEvent); } if (!_enabled || !isVisible) { dontDraw = true; } if (dontDraw) { overlay.HideOverlay(handle); dontDraw = false; return; } else if (dontUpdate) { dontUpdate = false; return; } var tex = new Texture_t(); tex.handle = texture.GetNativeTexturePtr(); tex.eType = OpenVR_Handler.instance.textureType; tex.eColorSpace = EColorSpace.Auto; var textureBounds = new VRTextureBounds_t(); textureBounds.uMin = (0 + uvOffset.x) * uvOffset.z; textureBounds.vMin = (1 + uvOffset.y) * uvOffset.w; textureBounds.uMax = (1 + uvOffset.x) * uvOffset.z; textureBounds.vMax = (0 + uvOffset.y) * uvOffset.w; var offset = new SteamVR_Utils.RigidTransform(origin, transform).ToHmdMatrix34(); var vecMouseScale = new HmdVector2_t(); vecMouseScale.v0 = mouseScale.x; vecMouseScale.v1 = mouseScale.y; overlay.SetOverlayTexture(handle, ref tex); overlay.SetOverlayTextureBounds(handle, ref textureBounds); if (useWorldSpaceForOverlay) { overlay.SetOverlayTransformAbsolute(handle, trackingSpace, ref offset); } overlay.SetOverlayAlpha(handle, opacity); overlay.SetOverlayWidthInMeters(handle, scale); if (highQualityOverlay) { overlay.SetHighQualityOverlay(handle); } overlay.SetOverlayMouseScale(handle, ref vecMouseScale); overlay.SetOverlayInputMethod(handle, inputMethod); overlay.SetOverlayFlag(handle, VROverlayFlags.ShowTouchPadScrollWheel, enableScroller); }
//-------------------------------------------------------------------------- //初期化処理 private void Start() { #pragma warning disable 0219 string Tag = "[" + this.GetType().Name + ":" + System.Reflection.MethodBase.GetCurrentMethod(); //クラス名とメソッド名を自動取得 #pragma warning restore 0219 Debug.Log(Tag + "Begin"); var openVRError = EVRInitError.None; var overlayError = EVROverlayError.None; error = false; oldshow = !show; //フレームレートを90fpsにする。(しないと無限に早くなることがある) Application.targetFrameRate = 90; Debug.Log(Tag + "Set Frame Rate 90"); //JSON読み込み Debug.Log(Tag + "Load JSON"); loadJSON(); InstanceKeyText.text = ""; //複数起動用キー if (Environment.GetCommandLineArgs().Length >= 3) { Debug.Log(Environment.GetCommandLineArgs()[1]); Debug.Log(Environment.GetCommandLineArgs()[2]); //引数に合わせて一時的にKeyを変更する if (Environment.GetCommandLineArgs()[1] == "overlaykey") { config.OverlayKeyName = Environment.GetCommandLineArgs()[2]; config.OverlayFriendlyName = Environment.GetCommandLineArgs()[2]; //サブインスタンス表示 InstanceKeyText.text = config.OverlayKeyName; } } //表示用 OverlayKeyName = config.OverlayKeyName; OverlayFriendlyName = config.OverlayFriendlyName; //OpenVRの初期化 openvr = OpenVR.Init(ref openVRError, EVRApplicationType.VRApplication_Overlay); if (openVRError != EVRInitError.None) { Debug.LogError(Tag + "OpenVRの初期化に失敗." + openVRError.ToString()); //エラーを告知し5秒後に終了 DOVirtual.DelayedCall(5f, () => { ApplicationQuit(); }); ProcessError(); return; } //オーバーレイ機能の初期化 overlay = OpenVR.Overlay; overlayError = overlay.CreateOverlay(config.OverlayKeyName, config.OverlayFriendlyName, ref overlayHandle); if (overlayError != EVROverlayError.None) { Debug.LogError(Tag + "Overlayの初期化に失敗. " + overlayError.ToString()); //エラーを告知し5秒後に終了 DOVirtual.DelayedCall(5f, () => { ApplicationQuit(); }); ProcessError(); return; } //オーバーレイに渡すテクスチャ種類の設定 var OverlayTextureBounds = new VRTextureBounds_t(); var isOpenGL = SystemInfo.graphicsDeviceVersion.Contains("OpenGL"); if (isOpenGL) { //pGLuintTexture overlayTexture.eType = ETextureType.OpenGL; //上下反転しない OverlayTextureBounds.uMin = 1; OverlayTextureBounds.vMin = 0; OverlayTextureBounds.uMax = 1; OverlayTextureBounds.vMax = 0; overlay.SetOverlayTextureBounds(overlayHandle, ref OverlayTextureBounds); } else { //pTexture overlayTexture.eType = ETextureType.DirectX; //上下反転する OverlayTextureBounds.uMin = 0; OverlayTextureBounds.vMin = 1; OverlayTextureBounds.uMax = 1; OverlayTextureBounds.vMax = 0; overlay.SetOverlayTextureBounds(overlayHandle, ref OverlayTextureBounds); } //-------- showDevices(); Debug.Log(Tag + "初期化完了しました"); }
protected override void Render() { EnsureDllsLoaded(); Lock = true; EVRInitError initError = EVRInitError.None; Valve.VR.OpenVR.Init(ref initError); if (initError != EVRInitError.None) { throw new Exception("OpenVR init error " + initError + ": " + Valve.VR.OpenVR.GetStringForHmdError(initError)); } CVRSystem hmd = Valve.VR.OpenVR.System; CVRCompositor compositor = Valve.VR.OpenVR.Compositor; uint targetWidth = 0, targetHeight = 0; hmd.GetRecommendedRenderTargetSize(ref targetWidth, ref targetHeight); float sceneWidth = (float)targetWidth; float sceneHeight = (float)targetHeight; float l_left = 0.0f, l_right = 0.0f, l_top = 0.0f, l_bottom = 0.0f; hmd.GetProjectionRaw(EVREye.Eye_Left, ref l_left, ref l_right, ref l_top, ref l_bottom); float r_left = 0.0f, r_right = 0.0f, r_top = 0.0f, r_bottom = 0.0f; hmd.GetProjectionRaw(EVREye.Eye_Right, ref r_left, ref r_right, ref r_top, ref r_bottom); Vector2 tanHalfFov = new Vector2( Math.Max(Math.Max(-l_left, l_right), Math.Max(-r_left, r_right)), Math.Max(Math.Max(-l_top, l_bottom), Math.Max(-r_top, r_bottom)) ); VRTextureBounds_t[] textureBounds = new VRTextureBounds_t[2]; textureBounds[0].uMin = 0.5f + 0.5f * l_left / tanHalfFov.X; textureBounds[0].uMax = 0.5f + 0.5f * l_right / tanHalfFov.X; textureBounds[0].vMin = 0.5f - 0.5f * l_bottom / tanHalfFov.Y; textureBounds[0].vMax = 0.5f - 0.5f * l_top / tanHalfFov.Y; textureBounds[1].uMin = 0.5f + 0.5f * r_left / tanHalfFov.X; textureBounds[1].uMax = 0.5f + 0.5f * r_right / tanHalfFov.X; textureBounds[1].vMin = 0.5f - 0.5f * r_bottom / tanHalfFov.Y; textureBounds[1].vMax = 0.5f - 0.5f * r_top / tanHalfFov.Y; float aspect = tanHalfFov.X / tanHalfFov.Y; float lookFov = (float)(2.0f * Math.Atan(tanHalfFov.Y) * 180 / Math.PI); Texture2DDescription eyeTextureDescription = new Texture2DDescription() { Format = Format.R8G8B8A8_UNorm_SRgb, ArraySize = 1, MipLevels = 1, Width = (int)targetWidth, Height = (int)targetHeight, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default, BindFlags = BindFlags.RenderTarget, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.None }; Texture2DDescription eyeDepthTextureDescription = new Texture2DDescription() { Format = Format.D32_Float_S8X24_UInt, ArraySize = 1, MipLevels = 1, Width = (int)targetWidth, Height = (int)targetHeight, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default, BindFlags = BindFlags.DepthStencil, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.None }; ///// CUBE //var cubeEffect = new SharpDX.Toolkit.Graphics.BasicEffect(_gd) //{ // //PreferPerPixelLighting = false, // //TextureEnabled = false, // LightingEnabled = true, // //DiffuseColor = new Vector4(0.5f,0.5f,0.5f,1f), // Sampler = _gd.SamplerStates.AnisotropicClamp //}; //cubeEffect.EnableDefaultLighting(); //var cube = SharpDX.Toolkit.Graphics.GeometricPrimitive.Teapot.New(_gd, 1, 8, false); ///// END using (_device = new Device(DriverType.Hardware, DeviceCreationFlags.BgraSupport, new FeatureLevel[] { FeatureLevel.Level_10_0 })) using (DeviceContext context = _device.ImmediateContext) using (_gd = SharpDX.Toolkit.Graphics.GraphicsDevice.New(_device)) //using (SharpDX.Toolkit.Graphics.GeometricPrimitive primitive = GraphicTools.CreateGeometry(_projection, _gd, false)) using (customEffectL = GetCustomEffect(_gd)) using (customEffectR = GetCustomEffect(_gd)) using (Texture2D leftEye = new Texture2D(_device, eyeTextureDescription)) using (RenderTargetView leftEyeView = new RenderTargetView(_device, leftEye)) using (Texture2D leftEyeDepth = new Texture2D(_device, eyeDepthTextureDescription)) using (DepthStencilView leftEyeDepthView = new DepthStencilView(_device, leftEyeDepth)) using (Texture2D rightEye = new Texture2D(_device, eyeTextureDescription)) using (RenderTargetView rightEyeView = new RenderTargetView(_device, rightEye)) using (Texture2D rightEyeDepth = new Texture2D(_device, eyeDepthTextureDescription)) using (DepthStencilView rightEyeDepthView = new DepthStencilView(_device, rightEyeDepth)) using (vrui = new VRUI(_device, _gd)) { //primitive = GraphicTools.CreateGeometry(Projection, _gd, false); Stopwatch stopwatch = new Stopwatch(); Texture_t leftEyeTex = new Texture_t() { eColorSpace = EColorSpace.Gamma, eType = EGraphicsAPIConvention.API_DirectX, handle = leftEye.NativePointer }; Texture_t rightEyeTex = new Texture_t() { eColorSpace = EColorSpace.Gamma, eType = EGraphicsAPIConvention.API_DirectX, handle = rightEye.NativePointer }; TrackedDevicePose_t[] renderPoseArray = new TrackedDevicePose_t[16]; TrackedDevicePose_t[] gamePoseArray = new TrackedDevicePose_t[16]; TrackedDevicePose_t pose = new TrackedDevicePose_t(); try { // Start with default background SetDefaultScene(); while (!abort) { UpdateContentIfRequested(); float deltaTime = (float)stopwatch.Elapsed.TotalSeconds; stopwatch.Restart(); compositor.WaitGetPoses(renderPoseArray, gamePoseArray); if (renderPoseArray[Valve.VR.OpenVR.k_unTrackedDeviceIndex_Hmd].bPoseIsValid) { pose = gamePoseArray[Valve.VR.OpenVR.k_unTrackedDeviceIndex_Hmd]; } foreach (EVREye eye in new EVREye[] { EVREye.Eye_Left, EVREye.Eye_Right }) { DepthStencilView currentEyeDepthView = (eye == EVREye.Eye_Left) ? leftEyeDepthView : rightEyeDepthView; RenderTargetView currentEyeView = (eye == EVREye.Eye_Left) ? leftEyeView : rightEyeView; // Setup targets and viewport for rendering context.OutputMerger.SetTargets(currentEyeDepthView, currentEyeView); context.ClearDepthStencilView(currentEyeDepthView, DepthStencilClearFlags.Depth, 1.0f, 0); context.ClearRenderTargetView(currentEyeView, Color.Black); context.Rasterizer.SetViewport(new Viewport(0, 0, (int)targetWidth, (int)targetHeight, 0.0f, 1.0f)); Quaternion lookRotation; // = pose.mDeviceToAbsoluteTracking.GetRotation(); Vector3 lookPosition; // = pose.mDeviceToAbsoluteTracking.GetPosition(); Vector3 scale; Matrix eyePose = hmd.GetEyeToHeadTransform(eye).RebuildTRSMatrix() * pose.mDeviceToAbsoluteTracking.RebuildTRSMatrix(); eyePose.Decompose(out scale, out lookRotation, out lookPosition); Matrix rotationMatrix = Matrix.RotationQuaternion(lookRotation); Vector3 lookUp = Vector3.Transform(Vector3.Up, rotationMatrix).ToVector3(); Vector3 lookAt = Vector3.Transform(Vector3.ForwardRH, rotationMatrix).ToVector3(); //Console.WriteLine($"OpenVR {eye} up: {lookUp:00.00} at: {lookAt:00.00} position:{lookPosition:00.00}"); Matrix viewMatrix = Matrix.LookAtRH(lookPosition, lookPosition + lookAt, lookUp); Matrix pm1 = Matrix.PerspectiveFovLH(lookFov * ((float)Math.PI / 180f), aspect, 0.001f, 100.0f); //Matrix pm2 = hmd.GetProjectionMatrix(eye, 0.001f, 100f, EGraphicsAPIConvention.API_DirectX).ToProjMatrix(); Matrix projectionMatrix = pm1; Matrix worldMatrix = Matrix.Translation(lookPosition); if (Logic.Instance.settings.OpenVRReverse) { worldMatrix = Matrix.RotationY(180) * worldMatrix; } Matrix MVP = worldMatrix * viewMatrix * projectionMatrix; customEffectL.Parameters["WorldViewProj"].SetValue(MVP); customEffectR.Parameters["WorldViewProj"].SetValue(MVP); lock (localCritical) { if (eye == EVREye.Eye_Left) { primitive?.Draw(customEffectL); } if (eye == EVREye.Eye_Right) { primitive?.Draw(customEffectR); } } if (eye == EVREye.Eye_Left) { Vector3 fixedLookPosition = Vector3.Transform(lookPosition, MVP).ToVector3(); Vector3 fixedLookAt = Vector3.Transform(lookPosition + Vector3.ForwardLH, MVP).ToVector3() - fixedLookPosition; Vector3 fixedLookUp = Vector3.Transform(lookPosition + Vector3.Up, MVP).ToVector3() - fixedLookPosition; fixedLookAt.Normalize(); fixedLookUp.Normalize(); Quaternion fixedLookRotation = Quaternion.LookAtRH(Vector3.Zero, fixedLookAt, fixedLookUp); //fixedLookRotation.X *= -1; //fixedLookRotation.Y *= -1; fixedLookRotation.Z *= -1; //if(eye == EVREye.Eye_Left) // fixedLookRotation.Invert(); //Mirror effect of rotation along z axis by flipping x and y elements of the quaternion. //http://stackoverflow.com/a/32482386/785171 //float t = fixedLookRotation.X; //fixedLookRotation.X = fixedLookRotation.Y; //fixedLookRotation.Y = t; //fixedLookRotation = new Quaternion(1, 0, 0, 0) * fixedLookRotation; //fixedLookRotation = new Quaternion(0, 0, 1, 0) * fixedLookRotation; LoggerManager.Publish("openvr.forward", fixedLookAt); LoggerManager.Publish("openvr.up", fixedLookUp); // TODO: normalize ProvideLook?.Invoke(fixedLookPosition, fixedLookRotation, lookFov); } // reset UI position every frame if it is not visible if (vrui.isUIHidden) { vrui.SetWorldPosition(viewMatrix.Forward, lookPosition, false); } vrui.Draw(Media, currentTime, Duration); vrui.Render(deltaTime, viewMatrix, projectionMatrix, lookPosition, ShouldShowVRUI); //// controllers: //cubeEffect.View = viewMatrix; //cubeEffect.Projection = projectionMatrix; //for (uint controller = 1 /*skip hmd*/; controller < Valve.VR.OpenVR.k_unMaxTrackedDeviceCount; controller++) //{ // VRControllerState_t controllerState = default(VRControllerState_t); // //var controllerPose = renderPoseArray[controller]; // //if (hmd.GetControllerState(controller, ref controllerState)) { // Vector3 pos = renderPoseArray[controller].mDeviceToAbsoluteTracking.GetPosition(); // Quaternion rot = renderPoseArray[controller].mDeviceToAbsoluteTracking.GetRotation(); // rot = rot * new Quaternion(0, 1, 0, 0); // float s = controllerState.ulButtonPressed > 0 ? 0.5f : 0.1f; // cubeEffect.World = Matrix.Scaling(s) * Matrix.RotationQuaternion(rot) * Matrix.Translation(pos); // cube.Draw(cubeEffect); // //} //} } // RENDER TO HMD EVRCompositorError errorLeft = compositor.Submit( EVREye.Eye_Left, ref leftEyeTex, ref textureBounds[0], EVRSubmitFlags.Submit_Default ); EVRCompositorError errorRight = compositor.Submit( EVREye.Eye_Right, ref rightEyeTex, ref textureBounds[1], EVRSubmitFlags.Submit_Default ); if (errorLeft != EVRCompositorError.None) { throw new HeadsetError("VR Compositor failure (left): " + errorLeft); } if (errorRight != EVRCompositorError.None) { throw new HeadsetError("VR Compositor failure (right): " + errorRight); } } ; } finally { Valve.VR.OpenVR.Shutdown(); primitive?.Dispose(); context.ClearState(); context.Flush(); } } }
/// <summary> /// Push Updates to our Overlay to the OpenVR System /// </summary> private void UpdateOverlay() { var overlay = OpenVR.Overlay; if (overlay == null) { return; } if (OverlayTexture != null) { var error = overlay.ShowOverlay(_handle); if (error == EVROverlayError.InvalidHandle || error == EVROverlayError.UnknownOverlay) { if (overlay.FindOverlay(Key, ref _handle) != EVROverlayError.None) { return; } } var tex = new Texture_t { handle = OverlayTexture.GetNativeTexturePtr(), eType = SteamVR.instance.graphicsAPI, eColorSpace = EColorSpace.Auto }; overlay.SetOverlayColor(_handle, 1f, 1f, 1f); //overlay.SetOverlayGamma(_handle, 2.2f); // Doesn't exist yet :( overlay.SetOverlayTexture(_handle, ref tex); overlay.SetOverlayAlpha(_handle, AnimateOnGaze == AnimationType.Alpha || AnimateOnGaze == AnimationType.AlphaAndScale ? _alpha : Alpha); overlay.SetOverlayWidthInMeters(_handle, AnimateOnGaze == AnimationType.Scale || AnimateOnGaze == AnimationType.AlphaAndScale ? _scale : Scale); overlay.SetOverlayAutoCurveDistanceRangeInMeters(_handle, CurvedRange.x, CurvedRange.y); var textureBounds = new VRTextureBounds_t { uMin = (0 + UvOffset.x) * UvOffset.z, vMin = (1 + UvOffset.y) * UvOffset.w, uMax = (1 + UvOffset.x) * UvOffset.z, vMax = (0 + UvOffset.y) * UvOffset.w }; overlay.SetOverlayTextureBounds(_handle, ref textureBounds); var vecMouseScale = new HmdVector2_t { v0 = MouseScale.x, v1 = MouseScale.y }; overlay.SetOverlayMouseScale(_handle, ref vecMouseScale); if (_anchor != OpenVR.k_unTrackedDeviceIndexInvalid) // Attached to some HOTK_TrackedDevice, used for Controllers { var t = GetOverlayPosition(); overlay.SetOverlayTransformTrackedDeviceRelative(_handle, _anchor, ref t); } else if (AnchorDevice == AttachmentDevice.World) // Attached to World { var t = GetOverlayPosition(); overlay.SetOverlayTransformAbsolute(_handle, SteamVR_Render.instance.trackingSpace, ref t); } else { var vrcam = SteamVR_Render.Top(); if (vrcam != null && vrcam.origin != null) // Attached to Camera (We are Rendering) { var offset = new SteamVR_Utils.RigidTransform(vrcam.origin, transform); offset.pos.x /= vrcam.origin.localScale.x; offset.pos.y /= vrcam.origin.localScale.y; offset.pos.z /= vrcam.origin.localScale.z; var t = offset.ToHmdMatrix34(); overlay.SetOverlayTransformAbsolute(_handle, SteamVR_Render.instance.trackingSpace, ref t); } else // Attached to Camera (We are Not Rendering) { var t = GetOverlayPosition(); overlay.SetOverlayTransformTrackedDeviceRelative(_handle, 0, ref t); } } overlay.SetOverlayInputMethod(_handle, InputMethod); if (Highquality) { if (HighQualityOverlay != this && HighQualityOverlay != null) { if (HighQualityOverlay.Highquality) { Debug.LogWarning("Only one Overlay can be in HighQuality mode as per the OpenVR API."); HighQualityOverlay.Highquality = false; } HighQualityOverlay = this; } else if (HighQualityOverlay == null) { HighQualityOverlay = this; } overlay.SetHighQualityOverlay(_handle); overlay.SetOverlayFlag(_handle, VROverlayFlags.Curved, Curved); overlay.SetOverlayFlag(_handle, VROverlayFlags.RGSS4X, Antialias); } else if (overlay.GetHighQualityOverlay() == _handle) { overlay.SetHighQualityOverlay(OpenVR.k_ulOverlayHandleInvalid); } } else { overlay.HideOverlay(_handle); } }
public override EVRCompositorError Submit(EVREye eEye,ref Texture_t pTexture,ref VRTextureBounds_t pBounds,EVRSubmitFlags nSubmitFlags) { CheckIfUsable(); EVRCompositorError result = VRNativeEntrypoints.VR_IVRCompositor_Submit(m_pVRCompositor,eEye,ref pTexture,ref pBounds,nSubmitFlags); return result; }
public override VRCompositorError Submit(Hmd_Eye eEye,GraphicsAPIConvention eTextureType,IntPtr pTexture,ref VRTextureBounds_t pBounds,VRSubmitFlags_t nSubmitFlags) { CheckIfUsable(); VRCompositorError result = VRNativeEntrypoints.VR_IVRCompositor_Submit(m_pVRCompositor,eEye,eTextureType,pTexture,ref pBounds,nSubmitFlags); return result; }
public abstract EVRCompositorError Submit(EVREye eEye,ref Texture_t pTexture,ref VRTextureBounds_t pBounds,EVRSubmitFlags nSubmitFlags);
public void UpdateOverlay() { var overlay = OpenVR.Overlay; if (overlay == null) { return; } if (texture != null) { var error = overlay.ShowOverlay(handle); if (error == EVROverlayError.InvalidHandle || error == EVROverlayError.UnknownOverlay) { if (overlay.FindOverlay(overlayKey, ref handle) != EVROverlayError.None) { return; } } var tex = new Texture_t(); tex.handle = texture.GetNativeTexturePtr(); switch (SystemInfo.graphicsDeviceType) { case UnityEngine.Rendering.GraphicsDeviceType.OpenGLCore: case UnityEngine.Rendering.GraphicsDeviceType.OpenGLES2: case UnityEngine.Rendering.GraphicsDeviceType.OpenGLES3: tex.eType = ETextureType.OpenGL; break; case UnityEngine.Rendering.GraphicsDeviceType.Vulkan: tex.eType = ETextureType.Vulkan; break; default: tex.eType = ETextureType.DirectX; break; } tex.eColorSpace = EColorSpace.Auto; overlay.SetOverlayTexture(handle, ref tex); overlay.SetOverlayAlpha(handle, alpha); overlay.SetOverlayWidthInMeters(handle, WidthInMeters); var curvedRange = new Vector2(1, 2); overlay.SetOverlayAutoCurveDistanceRangeInMeters(handle, curvedRange.x, curvedRange.y); var textureBounds = new VRTextureBounds_t(); textureBounds.uMin = (0 + uvOffset.x) * uvOffset.z; textureBounds.vMin = (1 + uvOffset.y) * uvOffset.w; textureBounds.uMax = (1 + uvOffset.x) * uvOffset.z; textureBounds.vMax = (0 + uvOffset.y) * uvOffset.w; overlay.SetOverlayTextureBounds(handle, ref textureBounds); var vecMouseScale = new HmdVector2_t(); var mouseScale = new Vector2(1, 1); vecMouseScale.v0 = mouseScale.x; vecMouseScale.v1 = mouseScale.y; overlay.SetOverlayMouseScale(handle, ref vecMouseScale); if ((lastRenderPosition != RenderPosition || lastWidthInMeters != WidthInMeters || lastPositionOffset != PositionOffset)) { if (RayTargetQuad != null) { Destroy(RayTargetQuad); } //Ray飛ばし座標取得用のQuadを配置 RayTargetQuad = GameObject.CreatePrimitive(PrimitiveType.Quad); RayTargetQuad.GetComponent <MeshRenderer>().enabled = false; // 非表示にする RayTargetQuad.transform.SetParent(RenderPosition); RayTargetQuad.transform.localPosition = PositionOffset; RayTargetQuad.transform.localEulerAngles = Vector3.zero; RayTargetQuad.transform.localScale = new Vector3(WidthInMeters, (WidthInMeters / texture.width) * texture.height, 1.0f); lastRenderPosition = RenderPosition; lastWidthInMeters = WidthInMeters; lastPositionOffset = PositionOffset; } var offset = new SteamVR_Utils.RigidTransform(); if (RayTargetQuad != null) { offset.pos = RayTargetQuad.transform.position; offset.rot = RayTargetQuad.transform.rotation; } else { offset.pos = new Vector3(0, 0, 0); offset.rot = Quaternion.Euler(0, 0, 0); } var t = offset.ToHmdMatrix34(); overlay.SetOverlayTransformAbsolute(handle, SteamVR_Render.instance.trackingSpace, ref t); overlay.SetOverlayInputMethod(handle, VROverlayInputMethod.Mouse); } else { overlay.HideOverlay(handle); } }
public static extern void SetSubmitParams(VRTextureBounds_t boundsL, VRTextureBounds_t boundsR, EVRSubmitFlags nSubmitFlags);
public static Mesh CreateHiddenAreaMesh(HiddenAreaMesh_t src, VRTextureBounds_t bounds) { if (src.unTriangleCount == 0u) { return(null); } float[] array = new float[src.unTriangleCount * 3u * 2u]; Marshal.Copy(src.pVertexData, array, 0, array.Length); Vector3[] array2 = new Vector3[src.unTriangleCount * 3u + 12u]; int[] array3 = new int[src.unTriangleCount * 3u + 24u]; float num = 2f * bounds.uMin - 1f; float num2 = 2f * bounds.uMax - 1f; float num3 = 2f * bounds.vMin - 1f; float num4 = 2f * bounds.vMax - 1f; int num5 = 0; int num6 = 0; while ((long)num5 < (long)((ulong)(src.unTriangleCount * 3u))) { float x = SteamVR_Utils.Lerp(num, num2, array[num6++]); float y = SteamVR_Utils.Lerp(num3, num4, array[num6++]); array2[num5] = new Vector3(x, y, 0f); array3[num5] = num5; num5++; } int num7 = (int)(src.unTriangleCount * 3u); int num8 = num7; array2[num8++] = new Vector3(-1f, -1f, 0f); array2[num8++] = new Vector3(num, -1f, 0f); array2[num8++] = new Vector3(-1f, 1f, 0f); array2[num8++] = new Vector3(num, 1f, 0f); array2[num8++] = new Vector3(num2, -1f, 0f); array2[num8++] = new Vector3(1f, -1f, 0f); array2[num8++] = new Vector3(num2, 1f, 0f); array2[num8++] = new Vector3(1f, 1f, 0f); array2[num8++] = new Vector3(num, num3, 0f); array2[num8++] = new Vector3(num2, num3, 0f); array2[num8++] = new Vector3(num, num4, 0f); array2[num8++] = new Vector3(num2, num4, 0f); int num9 = num7; array3[num9++] = num7; array3[num9++] = num7 + 1; array3[num9++] = num7 + 2; array3[num9++] = num7 + 2; array3[num9++] = num7 + 1; array3[num9++] = num7 + 3; array3[num9++] = num7 + 4; array3[num9++] = num7 + 5; array3[num9++] = num7 + 6; array3[num9++] = num7 + 6; array3[num9++] = num7 + 5; array3[num9++] = num7 + 7; array3[num9++] = num7 + 1; array3[num9++] = num7 + 4; array3[num9++] = num7 + 8; array3[num9++] = num7 + 8; array3[num9++] = num7 + 4; array3[num9++] = num7 + 9; array3[num9++] = num7 + 10; array3[num9++] = num7 + 11; array3[num9++] = num7 + 3; array3[num9++] = num7 + 3; array3[num9++] = num7 + 11; array3[num9++] = num7 + 6; return(new Mesh { vertices = array2, triangles = array3, bounds = new Bounds(Vector3.zero, new Vector3(3.40282347E+38f, 3.40282347E+38f, 3.40282347E+38f)) }); }
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(); } }
protected override void BaseInitialize() { if (this.HmdDetected) { var rtManager = this.adapter.Graphics.RenderTargetManager as RenderTargetManager; uint recommendedWidth = 0; uint recommendedHeight = 0; this.Hmd.GetRecommendedRenderTargetSize(ref recommendedWidth, ref recommendedHeight); int rtWidth = (int)recommendedWidth * 2; int rtHeight = (int)recommendedHeight; var eyeDepthTexture = rtManager.CreateDepthTexture(rtWidth, rtHeight, this.msaaSampleCount); if (this.msaaSampleCount > 1) { // Create MSAA renderTarget this.msaaRenderTarget = rtManager.CreateRenderTarget(rtWidth, rtHeight, PixelFormat.R8G8B8A8, this.msaaSampleCount); this.msaaRenderTarget.DepthTexture = eyeDepthTexture; } this.swapRenderTarget = rtManager.CreateRenderTarget(rtWidth, rtHeight, PixelFormat.R8G8B8A8); if (this.msaaSampleCount == 1) { this.swapRenderTarget.DepthTexture = eyeDepthTexture; } var swapDXRenderTarget = rtManager.TargetFromHandle <DXRenderTarget>(this.swapRenderTarget.TextureHandle); this.swapTexture = new Texture_t() { handle = swapDXRenderTarget.NativeTexture, eColorSpace = EColorSpace.Auto, eType = ETextureType.DirectX }; this.leftEyeTextureBounds = new VRTextureBounds_t() { uMin = 0, uMax = 0.5f, vMin = 0, vMax = 1f }; this.rightEyeTextureBounds = new VRTextureBounds_t() { uMin = 0.5f, uMax = 1f, vMin = 0, vMax = 1f }; // Create a set of layers to submit. this.EyeTextures = new VREyeTexture[2]; for (int eyeIndex = 0; eyeIndex < 2; eyeIndex++) { var eyeTexture = new VREyeTexture(); this.EyeTextures[eyeIndex] = eyeTexture; // Retrieve size and position of the texture for the current eye. eyeTexture.Viewport = new Viewport( recommendedWidth * eyeIndex / (float)this.swapRenderTarget.Width, 0, recommendedWidth / (float)this.swapRenderTarget.Width, recommendedHeight / (float)this.swapRenderTarget.Height); eyeTexture.RenderTarget = (this.msaaSampleCount > 1) ? this.msaaRenderTarget : this.swapRenderTarget; } this.HMDMirrorRenderTarget = this.swapRenderTarget; } WaveServices.RegisterService(new OpenVRService()); this.IsConnected = this.Hmd != null; base.BaseInitialize(); }
public void UpdateCursorOverlay() { var overlay = OpenVR.Overlay; if (overlay == null || guiOverlay == null) { return; } if (CursorTexture != null && guiOverlay.showCursor && guiOverlay.cursorTargetTransform != null) { var error = overlay.ShowOverlay(handle); if (error == EVROverlayError.InvalidHandle || error == EVROverlayError.UnknownOverlay) { if (overlay.FindOverlay(overlayKey, ref handle) != EVROverlayError.None) { return; } } var tex = new Texture_t(); tex.handle = CursorTexture.GetNativeTexturePtr(); tex.eType = SteamVR.instance.textureType; tex.eColorSpace = EColorSpace.Auto; overlay.SetOverlayTexture(handle, ref tex); overlay.SetOverlayAlpha(handle, 1.0f); overlay.SetOverlayWidthInMeters(handle, WidthInMeters); var curvedRange = new Vector2(1, 2); overlay.SetOverlayAutoCurveDistanceRangeInMeters(handle, curvedRange.x, curvedRange.y); var uvOffset = new Vector4(0, 0, 1, 1); var textureBounds = new VRTextureBounds_t(); textureBounds.uMin = (0 + uvOffset.x) * uvOffset.z; textureBounds.vMin = (1 + uvOffset.y) * uvOffset.w; textureBounds.uMax = (1 + uvOffset.x) * uvOffset.z; textureBounds.vMax = (0 + uvOffset.y) * uvOffset.w; overlay.SetOverlayTextureBounds(handle, ref textureBounds); var vecMouseScale = new HmdVector2_t(); var mouseScale = new Vector2(1, 1); vecMouseScale.v0 = mouseScale.x; vecMouseScale.v1 = mouseScale.y; overlay.SetOverlayMouseScale(handle, ref vecMouseScale); if (cursorPosition == null) { cursorPosition = (new GameObject()).transform; cursorPosition.SetParent(guiOverlay.cursorTargetTransform); cursorPosition.localEulerAngles = Vector3.zero; } var offset = new SteamVR_Utils.RigidTransform(); var texWidth = guiOverlay.cursorTargetTransform.localScale.x; var texHeight = guiOverlay.cursorTargetTransform.localScale.y; var curWidth = WidthInMeters; var curHeight = (WidthInMeters / CursorTexture.width) * CursorTexture.height; var scaleWidth = curWidth / texWidth; var scaleHeight = curHeight / texHeight; cursorPosition.localPosition = new Vector3(guiOverlay.cursorPosition.x - 0.5f + (scaleWidth / 2), 0.5f - guiOverlay.cursorPosition.y - (scaleHeight / 2), -0.0f); offset.pos = cursorPosition.position; offset.rot = cursorPosition.rotation; var t = offset.ToHmdMatrix34(); overlay.SetOverlayTransformAbsolute(handle, SteamVR_Render.instance.trackingSpace, ref t); overlay.SetOverlaySortOrder(handle, 1); //SortOrderは数字が大きいほうが後からレンダリングされる overlay.SetOverlayInputMethod(handle, VROverlayInputMethod.Mouse); } else { overlay.HideOverlay(handle); } }
private SteamVR() { hmd = OpenVR.System; Debug.Log("Connected to " + hmd_TrackingSystemName + ":" + hmd_SerialNumber); compositor = OpenVR.Compositor; overlay = OpenVR.Overlay; // Setup render values uint w = 0, h = 0; hmd.GetRecommendedRenderTargetSize(ref w, ref h); sceneWidth = w; sceneHeight = h; float l_left = 0.0f, l_right = 0.0f, l_top = 0.0f, l_bottom = 0.0f; hmd.GetProjectionRaw(EVREye.Eye_Left, ref l_left, ref l_right, ref l_top, ref l_bottom); float r_left = 0.0f, r_right = 0.0f, r_top = 0.0f, r_bottom = 0.0f; hmd.GetProjectionRaw(EVREye.Eye_Right, ref r_left, ref r_right, ref r_top, ref r_bottom); tanHalfFov = new Vector2(Mathf.Max(-l_left, l_right, -r_left, r_right), Mathf.Max(-l_top, l_bottom, -r_top, r_bottom)); textureBounds = new VRTextureBounds_t[2]; textureBounds[0].uMin = 0.5f + 0.5f * l_left / tanHalfFov.x; textureBounds[0].uMax = 0.5f + 0.5f * l_right / tanHalfFov.x; textureBounds[0].vMin = 0.5f - 0.5f * l_bottom / tanHalfFov.y; textureBounds[0].vMax = 0.5f - 0.5f * l_top / tanHalfFov.y; textureBounds[1].uMin = 0.5f + 0.5f * r_left / tanHalfFov.x; textureBounds[1].uMax = 0.5f + 0.5f * r_right / tanHalfFov.x; textureBounds[1].vMin = 0.5f - 0.5f * r_bottom / tanHalfFov.y; textureBounds[1].vMax = 0.5f - 0.5f * r_top / tanHalfFov.y; // Grow the recommended size to account for the overlapping fov sceneWidth = sceneWidth / Mathf.Max(textureBounds[0].uMax - textureBounds[0].uMin, textureBounds[1].uMax - textureBounds[1].uMin); sceneHeight = sceneHeight / Mathf.Max(textureBounds[0].vMax - textureBounds[0].vMin, textureBounds[1].vMax - textureBounds[1].vMin); aspect = tanHalfFov.x / tanHalfFov.y; fieldOfView = 2.0f * Mathf.Atan(tanHalfFov.y) * Mathf.Rad2Deg; eyes = new[] { new SteamVR_Utils.RigidTransform(hmd.GetEyeToHeadTransform(EVREye.Eye_Left)), new SteamVR_Utils.RigidTransform(hmd.GetEyeToHeadTransform(EVREye.Eye_Right)) }; switch (SystemInfo.graphicsDeviceType) { #if (UNITY_5_4) case UnityEngine.Rendering.GraphicsDeviceType.OpenGL2: #endif case GraphicsDeviceType.OpenGLCore: case GraphicsDeviceType.OpenGLES2: case GraphicsDeviceType.OpenGLES3: textureType = ETextureType.OpenGL; break; #if !(UNITY_5_4) case GraphicsDeviceType.Vulkan: textureType = ETextureType.Vulkan; break; #endif default: textureType = ETextureType.DirectX; break; } SteamVR_Events.Initializing.Listen(OnInitializing); SteamVR_Events.Calibrating.Listen(OnCalibrating); SteamVR_Events.OutOfRange.Listen(OnOutOfRange); SteamVR_Events.DeviceConnected.Listen(OnDeviceConnected); SteamVR_Events.NewPoses.Listen(OnNewPoses); }
private void Update() { SteamVR_TrackedCamera.VideoStreamTexture source = SteamVR_TrackedCamera.Source(undistorted); Texture2D texture = source.texture; Texture2D Righttexture = source.texture; if (texture == null) { return; } // Apply the latest texture to the material. This must be performed // every frame since the underlying texture is actually part of a ring // buffer which is updated in lock-step with its associated pose. // (You actually really only need to call any of the accessors which // internally call Update on the SteamVR_TrackedCamera.VideoStreamTexture). material.mainTexture = texture; // Adjust the height of the quad based on the aspect to keep the texels square. float aspect = (float)texture.width / texture.height; // The undistorted video feed has 'bad' areas near the edges where the original // square texture feed is stretched to undo the fisheye from the lens. // Therefore, you'll want to crop it to the specified frameBounds to remove this. if (cropped) { VRTextureBounds_t bounds = source.frameBounds; material.mainTextureOffset = new Vector2(bounds.uMin, bounds.vMin); float du = bounds.uMax - bounds.uMin; float dv = bounds.vMax - bounds.vMin; if (Left)//左目の表示 { material.mainTextureScale = new Vector2(du, dv / 2); } else//右目の表示 { material.mainTextureScale = new Vector2(du, -dv / 2); } aspect *= Mathf.Abs(du / dv); } else { material.mainTextureOffset = Vector2.zero; material.mainTextureScale = new Vector2(1, -1); } /* * target.localScale = new Vector3(1, 1.0f / aspect, 1); * * // Apply the pose that this frame was recorded at. * if (source.hasTracking) * { * SteamVR_Utils.RigidTransform rigidTransform = source.transform; * target.localPosition = rigidTransform.pos; * target.localRotation = rigidTransform.rot; * } */ // Apply the pose that this frame was recorded at. if (source.hasTracking) { Vector2 ProjectionScale = GetProjectionScale(source); Vector2 LocalScale = new Vector2(2.0f * ProjectionZ / ProjectionScale.x, 2.0f * ProjectionZ / ProjectionScale.y); if (Left)//左目の表示 { target.localScale = new Vector3(LocalScale.x, LocalScale.y / 2, 1.0f); } else//右目の表示 { target.localScale = new Vector3(LocalScale.x, -LocalScale.y / 2, 1.0f); } // var t = source.transform; target.localPosition = t.TransformPoint(new Vector3(0.0f, 0.0f, ProjectionZ)); target.localRotation = t.rot; } }
private SteamVR() { hmd = OpenVR.System; Debug.Log("Connected to " + hmd_TrackingSystemName + ":" + hmd_SerialNumber); compositor = OpenVR.Compositor; overlay = OpenVR.Overlay; // Setup render values uint w = 0, h = 0; hmd.GetRecommendedRenderTargetSize(ref w, ref h); sceneWidth = (float)w; sceneHeight = (float)h; float l_left = 0.0f, l_right = 0.0f, l_top = 0.0f, l_bottom = 0.0f; hmd.GetProjectionRaw(EVREye.Eye_Left, ref l_left, ref l_right, ref l_top, ref l_bottom); float r_left = 0.0f, r_right = 0.0f, r_top = 0.0f, r_bottom = 0.0f; hmd.GetProjectionRaw(EVREye.Eye_Right, ref r_left, ref r_right, ref r_top, ref r_bottom); tanHalfFov = new Vector2( Mathf.Max(-l_left, l_right, -r_left, r_right), Mathf.Max(-l_top, l_bottom, -r_top, r_bottom)); textureBounds = new VRTextureBounds_t[2]; textureBounds[0].uMin = 0.5f + 0.5f * l_left / tanHalfFov.x; textureBounds[0].uMax = 0.5f + 0.5f * l_right / tanHalfFov.x; textureBounds[0].vMin = 0.5f - 0.5f * l_bottom / tanHalfFov.y; textureBounds[0].vMax = 0.5f - 0.5f * l_top / tanHalfFov.y; textureBounds[1].uMin = 0.5f + 0.5f * r_left / tanHalfFov.x; textureBounds[1].uMax = 0.5f + 0.5f * r_right / tanHalfFov.x; textureBounds[1].vMin = 0.5f - 0.5f * r_bottom / tanHalfFov.y; textureBounds[1].vMax = 0.5f - 0.5f * r_top / tanHalfFov.y; #if (UNITY_5_3 || UNITY_5_2 || UNITY_5_1 || UNITY_5_0) SteamVR.Unity.SetSubmitParams(textureBounds[0], textureBounds[1], EVRSubmitFlags.Submit_Default); #endif // Grow the recommended size to account for the overlapping fov sceneWidth = sceneWidth / Mathf.Max(textureBounds[0].uMax - textureBounds[0].uMin, textureBounds[1].uMax - textureBounds[1].uMin); sceneHeight = sceneHeight / Mathf.Max(textureBounds[0].vMax - textureBounds[0].vMin, textureBounds[1].vMax - textureBounds[1].vMin); aspect = tanHalfFov.x / tanHalfFov.y; fieldOfView = 2.0f * Mathf.Atan(tanHalfFov.y) * Mathf.Rad2Deg; eyes = new SteamVR_Utils.RigidTransform[] { new SteamVR_Utils.RigidTransform(hmd.GetEyeToHeadTransform(EVREye.Eye_Left)), new SteamVR_Utils.RigidTransform(hmd.GetEyeToHeadTransform(EVREye.Eye_Right)) }; if (SystemInfo.graphicsDeviceVersion.StartsWith("OpenGL")) { textureType = ETextureType.OpenGL; } else { textureType = ETextureType.DirectX; } SteamVR_Utils.Event.Listen("initializing", OnInitializing); SteamVR_Utils.Event.Listen("calibrating", OnCalibrating); SteamVR_Utils.Event.Listen("out_of_range", OnOutOfRange); SteamVR_Utils.Event.Listen("device_connected", OnDeviceConnected); SteamVR_Utils.Event.Listen("new_poses", OnNewPoses); }
private SteamVR(System.IntPtr pHmd, System.IntPtr pCompositor, System.IntPtr pOverlay) { hmd = new CVRSystem(pHmd); Debug.Log("Connected to " + hmd_TrackingSystemName + ":" + hmd_SerialNumber); compositor = new CVRCompositor(pCompositor); overlay = new CVROverlay(pOverlay); var capacity = compositor.GetLastError(null, 0); if (capacity > 1) { var result = new System.Text.StringBuilder((int)capacity); compositor.GetLastError(result, capacity); Debug.Log("Compositor - " + result); } // Setup render values uint w = 0, h = 0; hmd.GetRecommendedRenderTargetSize(ref w, ref h); sceneWidth = (float)w; sceneHeight = (float)h; float l_left = 0.0f, l_right = 0.0f, l_top = 0.0f, l_bottom = 0.0f; hmd.GetProjectionRaw(Hmd_Eye.Eye_Left, ref l_left, ref l_right, ref l_top, ref l_bottom); float r_left = 0.0f, r_right = 0.0f, r_top = 0.0f, r_bottom = 0.0f; hmd.GetProjectionRaw(Hmd_Eye.Eye_Right, ref r_left, ref r_right, ref r_top, ref r_bottom); tanHalfFov = new Vector2( Mathf.Max(-l_left, l_right, -r_left, r_right), Mathf.Max(-l_top, l_bottom, -r_top, r_bottom)); textureBounds = new VRTextureBounds_t[2]; textureBounds[0].uMin = 0.5f + 0.5f * l_left / tanHalfFov.x; textureBounds[0].uMax = 0.5f + 0.5f * l_right / tanHalfFov.x; textureBounds[0].vMin = 0.5f - 0.5f * l_bottom / tanHalfFov.y; textureBounds[0].vMax = 0.5f - 0.5f * l_top / tanHalfFov.y; textureBounds[1].uMin = 0.5f + 0.5f * r_left / tanHalfFov.x; textureBounds[1].uMax = 0.5f + 0.5f * r_right / tanHalfFov.x; textureBounds[1].vMin = 0.5f - 0.5f * r_bottom / tanHalfFov.y; textureBounds[1].vMax = 0.5f - 0.5f * r_top / tanHalfFov.y; Unity.SetSubmitParams(textureBounds[0], textureBounds[1], VRSubmitFlags_t.Submit_Default); // Grow the recommended size to account for the overlapping fov sceneWidth = sceneWidth / Mathf.Max(textureBounds[0].uMax - textureBounds[0].uMin, textureBounds[1].uMax - textureBounds[1].uMin); sceneHeight = sceneHeight / Mathf.Max(textureBounds[0].vMax - textureBounds[0].vMin, textureBounds[1].vMax - textureBounds[1].vMin); aspect = tanHalfFov.x / tanHalfFov.y; fieldOfView = 2.0f * Mathf.Atan(tanHalfFov.y) * Mathf.Rad2Deg; eyes = new SteamVR_Utils.RigidTransform[] { new SteamVR_Utils.RigidTransform(hmd.GetEyeToHeadTransform(Hmd_Eye.Eye_Left)), new SteamVR_Utils.RigidTransform(hmd.GetEyeToHeadTransform(Hmd_Eye.Eye_Right)) }; if (SystemInfo.graphicsDeviceVersion.StartsWith("OpenGL")) { graphicsAPI = GraphicsAPIConvention.API_OpenGL; } else { graphicsAPI = GraphicsAPIConvention.API_DirectX; } SteamVR_Utils.Event.Listen("initializing", OnInitializing); SteamVR_Utils.Event.Listen("calibrating", OnCalibrating); SteamVR_Utils.Event.Listen("out_of_range", OnOutOfRange); SteamVR_Utils.Event.Listen("device_connected", OnDeviceConnected); SteamVR_Utils.Event.Listen("new_poses", OnNewPoses); }
/// <summary> /// Submits the VR view to the screen. /// </summary> public void Submit() { VREvent_t evt = new VREvent_t(); while (VR.PollNextEvent(ref evt, (uint)Marshal.SizeOf(typeof(VREvent_t)))) { // No need to do anything here! } TrackedDevicePose_t[] rposes = new TrackedDevicePose_t[OpenVR.k_unMaxTrackedDeviceCount]; TrackedDevicePose_t[] gposes = new TrackedDevicePose_t[OpenVR.k_unMaxTrackedDeviceCount]; EVRCompositorError merr = Compositor.WaitGetPoses(rposes, gposes); if (rposes[OpenVR.k_unTrackedDeviceIndex_Hmd].bPoseIsValid) { HmdMatrix34_t tmat = rposes[OpenVR.k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking; headMat = new Matrix4(tmat.m0, tmat.m1, tmat.m2, tmat.m3, tmat.m4, tmat.m5, tmat.m6, tmat.m7, tmat.m8, tmat.m9, tmat.m10, tmat.m11, 0, 0, 0, 1); headMat.Transpose(); HeadMatRot = headMat * Matrix4.CreateRotationX((float)(Math.PI * 0.5)); headMat = headMat * Matrix4.CreateRotationX((float)(Math.PI * 0.5)); headMat = headMat.ClearTranslation() * Matrix4.CreateTranslation(headMat.ExtractTranslation() * VRScale); headMat.Invert(); } if (merr != EVRCompositorError.None) { SysConsole.Output(OutputType.WARNING, "Posing error: " + merr); } Left = GetController(true); Right = GetController(false); if (!Compositor.CanRenderScene()) { SysConsole.Output(OutputType.WARNING, "Can't render VR scene!"); } Texture_t left = new Texture_t() { eColorSpace = EColorSpace.Auto, eType = EGraphicsAPIConvention.API_OpenGL, handle = new IntPtr(TheClient.Engine3D.MainView.CurrentFBOTexture) }; VRTextureBounds_t bounds = new VRTextureBounds_t() { uMin = 0f, uMax = 0.5f, vMin = 0f, vMax = 1f }; EVRCompositorError lerr = Compositor.Submit(EVREye.Eye_Left, ref left, ref bounds, EVRSubmitFlags.Submit_Default); if (lerr != EVRCompositorError.None) { SysConsole.Output(OutputType.WARNING, "Left eye error: " + lerr); } Texture_t right = new Texture_t() { eColorSpace = EColorSpace.Auto, eType = EGraphicsAPIConvention.API_OpenGL, handle = new IntPtr(TheClient.Engine3D.MainView.CurrentFBOTexture) }; VRTextureBounds_t rbounds = new VRTextureBounds_t() { uMin = 0.5f, uMax = 1f, vMin = 0f, vMax = 1f }; EVRCompositorError rerr = Compositor.Submit(EVREye.Eye_Right, ref right, ref rbounds, EVRSubmitFlags.Submit_Default); if (rerr != EVRCompositorError.None) { SysConsole.Output(OutputType.WARNING, "Right eye error: " + rerr); } }
private void Update() { if (Input.GetKeyDown(KeyCode.LeftArrow)) { ImageOffset += 1f / 128; } else if (Input.GetKeyDown(KeyCode.RightArrow)) { ImageOffset -= 1f / 128; } if (Input.GetKeyDown(KeyCode.Space)) { flipped = !flipped; } SteamVR_TrackedCamera.VideoStreamTexture source = SteamVR_TrackedCamera.Source(undistorted); Texture2D texture = source.texture; if (texture == null) { Debug.LogWarning("Texture from tracked camera was null."); return; } // Apply the latest texture to the material. This must be performed // every frame since the underlying texture is actually part of a ring // buffer which is updated in lock-step with its associated pose. // (You actually really only need to call any of the accessors which // internally call Update on the SteamVR_TrackedCamera.VideoStreamTexture). material.mainTexture = texture; // Adjust the height of the quad based on the aspect to keep the texels square. float aspect = (float)texture.width / texture.height; // The undistorted video feed has 'bad' areas near the edges where the original // square texture feed is stretched to undo the fisheye from the lens. // Therefore, you'll want to crop it to the specified frameBounds to remove this. if (cropped) { VRTextureBounds_t bounds = source.frameBounds; material.mainTextureOffset = new Vector2(bounds.uMin, bounds.vMin); float du = bounds.uMax - bounds.uMin; float dv = bounds.vMax - bounds.vMin; material.mainTextureScale = new Vector2(du, dv); aspect *= Mathf.Abs(du / dv); } else { material.mainTextureOffset = Vector2.zero; material.mainTextureScale = new Vector2(1, -1); } //target.localScale = new Vector3(1, 1.0f / aspect, 1); // Apply the pose that this frame was recorded at. if (source.hasTracking) { SteamVR_Utils.RigidTransform rigidTransform = source.transform; //target.localPosition = rigidTransform.pos; //target.localRotation = rigidTransform.rot; } }
/// <summary> /// Push Updates to our Overlay to the OpenVR System /// </summary> private void UpdateOverlay() { var overlay = OpenVR.Overlay; if (overlay == null) { return; } if (OverlayTexture != null) { var error = overlay.ShowOverlay(_handle); if (error == EVROverlayError.InvalidHandle || error == EVROverlayError.UnknownOverlay) { if (overlay.FindOverlay(HOTK_Overlay.Key + gameObject.GetInstanceID(), ref _handle) != EVROverlayError.None) { return; } } var tex = new Texture_t { handle = OverlayTexture.GetNativeTexturePtr(), eType = SteamVR.instance.graphicsAPI, eColorSpace = EColorSpace.Auto }; overlay.SetOverlayColor(_handle, 1f, 1f, 1f); //overlay.SetOverlayGamma(_handle, 2.2f); // Doesn't exist yet :( overlay.SetOverlayTexture(_handle, ref tex); overlay.SetOverlayAlpha(_handle, _alpha); overlay.SetOverlayWidthInMeters(_handle, _scale); var textureBounds = new VRTextureBounds_t { uMin = (0 + Overlay.UvOffset.x) * Overlay.UvOffset.z, vMin = (1 + Overlay.UvOffset.y) * Overlay.UvOffset.w, uMax = (1 + Overlay.UvOffset.x) * Overlay.UvOffset.z, vMax = (0 + Overlay.UvOffset.y) * Overlay.UvOffset.w }; overlay.SetOverlayTextureBounds(_handle, ref textureBounds); var vecMouseScale = new HmdVector2_t { v0 = 1f, v1 = (float)OverlayTexture.height / (float)OverlayTexture.width }; overlay.SetOverlayMouseScale(_handle, ref vecMouseScale); if (_anchor != OpenVR.k_unTrackedDeviceIndexInvalid) // Attached to some HOTK_TrackedDevice, used for Controllers { var t = GetOverlayPosition(); overlay.SetOverlayTransformTrackedDeviceRelative(_handle, _anchor, ref t); } else if (_anchorDevice == HOTK_Overlay.AttachmentDevice.World) // Attached to World { var t = GetOverlayPosition(); overlay.SetOverlayTransformAbsolute(_handle, SteamVR_Render.instance.trackingSpace, ref t); } else { var vrcam = SteamVR_Render.Top(); if (vrcam != null && vrcam.origin != null) // Attached to Camera (We are Rendering) { var offset = new SteamVR_Utils.RigidTransform(vrcam.origin, transform); offset.pos.x /= vrcam.origin.localScale.x; offset.pos.y /= vrcam.origin.localScale.y; offset.pos.z /= vrcam.origin.localScale.z; var t = offset.ToHmdMatrix34(); overlay.SetOverlayTransformAbsolute(_handle, SteamVR_Render.instance.trackingSpace, ref t); } else // Attached to Camera (We are Not Rendering) { var t = GetOverlayPosition(); overlay.SetOverlayTransformTrackedDeviceRelative(_handle, 0, ref t); } } overlay.SetOverlayInputMethod(_handle, InputMethod); } else { overlay.HideOverlay(_handle); } }
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); }); } }
void Start() { var openVRError = EVRInitError.None; var overlayError = EVROverlayError.None; //OpenVRの初期化 openvr = OpenVR.Init(ref openVRError, EVRApplicationType.VRApplication_Overlay); if (openVRError != EVRInitError.None) { Debug.LogError(Tag + "OpenVRの初期化に失敗." + openVRError.ToString()); error = true; return; } //オーバーレイ機能の初期化 overlay = OpenVR.Overlay; overlayError = overlay.CreateDashboardOverlay(OverlayKeyName, OverlayFriendlyName, ref overlayHandle, ref thumbnailHandle); if (overlayError != EVROverlayError.None) { Debug.LogError(Tag + "Overlayの初期化に失敗. " + overlayError.ToString()); error = true; return; } //マウス(Dashboardのときのみ有効) overlay.SetOverlayInputMethod(overlayHandle, VROverlayInputMethod.Mouse); //オーバーレイに渡すテクスチャ種類の設定 OverlayTextureBounds = new VRTextureBounds_t(); var isOpenGL = SystemInfo.graphicsDeviceVersion.Contains("OpenGL"); if (isOpenGL) { //pGLuintTexture overlayTexture.eType = ETextureType.OpenGL; thumbnailTexture.eType = ETextureType.OpenGL; //上下反転しない OverlayTextureBounds.uMin = 1; OverlayTextureBounds.vMin = 0; OverlayTextureBounds.uMax = 1; OverlayTextureBounds.vMax = 0; overlay.SetOverlayTextureBounds(thumbnailHandle, ref OverlayTextureBounds); } else { //pTexture overlayTexture.eType = ETextureType.DirectX; thumbnailTexture.eType = ETextureType.DirectX; //上下反転する OverlayTextureBounds.uMin = 0; OverlayTextureBounds.vMin = 1; OverlayTextureBounds.uMax = 1; OverlayTextureBounds.vMax = 0; overlay.SetOverlayTextureBounds(overlayHandle, ref OverlayTextureBounds); } //サムネイルテクスチャが存在するなら if (thumbnailTextureInput != null) { //サムネイルテクスチャの情報を取得 var thumWidth = thumbnailTextureInput.width; var thumHeight = thumbnailTextureInput.height; //作業用テクスチャの領域を確保 thumbnailTexture2D = new Texture2D(thumWidth, thumHeight, TextureFormat.RGBA32, false); //力技でコピーして圧縮を解除 if (isOpenGL) { for (int y = 0; y < thumHeight; y++) { for (int x = 0; x < thumWidth; x++) { thumbnailTexture2D.SetPixel(x, y, thumbnailTextureInput.GetPixel(x, y)); } } } else { //DirectXは上下反転 for (int y = 0; y < thumHeight; y++) { for (int x = 0; x < thumWidth; x++) { thumbnailTexture2D.SetPixel(x, thumHeight - y - 1, thumbnailTextureInput.GetPixel(x, y)); } } } //操作を反映 thumbnailTexture2D.Apply(); //ネイティブテクスチャを取得して設定 thumbnailTexture.handle = thumbnailTexture2D.GetNativeTexturePtr(); //サムネイル利用可能フラグを立てる thumbnailAvailable = true; } Debug.Log(Tag + "初期化完了しました"); }
public override VROverlayError SetOverlayTextureBounds(ulong ulOverlayHandle,ref VRTextureBounds_t pOverlayTextureBounds) { CheckIfUsable(); VROverlayError result = VRNativeEntrypoints.VR_IVROverlay_SetOverlayTextureBounds(m_pVROverlay,ulOverlayHandle,ref pOverlayTextureBounds); return result; }
public void Draw() { lock (_drawLock) { if (_ui == null || !_ui.ready) { return; } if (_ui.gameStarted) { // Update Device Tracking compositor.WaitGetPoses(currentPoses, nextPoses); if (currentPoses[headset].bPoseIsValid) { Convert(ref currentPoses[headset].mDeviceToAbsoluteTracking, ref head); } // 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.Translation(0, 0, -100.0f); var worldViewProjection = world * view * projection; //context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.VertexShader.SetConstantBuffer(0, shaderParameterBuffer); context.PixelShader.SetConstantBuffer(0, shaderParameterBuffer); //Shapes.Cube.Begin(context); //Shapes.Cube.Draw(context); //Shapes.Sphere.Begin(context); //Shapes.Sphere.Draw(context); DrawPixels(worldViewProjection); // 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); shaderParameters.WorldViewProjection = world * view * projection; shaderParameters.Diffuse = new Vector4(1, 1, 1, 1); context.UpdateSubresource(ref shaderParameters, shaderParameterBuffer); context.VertexShader.SetConstantBuffer(0, shaderParameterBuffer); context.PixelShader.SetConstantBuffer(0, shaderParameterBuffer); 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.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.Translation(0, 0, -100.0f); worldViewProjection = world * view * projection; //context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.VertexShader.SetConstantBuffer(0, shaderParameterBuffer); context.PixelShader.SetConstantBuffer(0, shaderParameterBuffer); //Shapes.Cube.Begin(context); //Shapes.Cube.Draw(context); //Shapes.Sphere.Begin(context); //Shapes.Sphere.Draw(context); DrawPixels(worldViewProjection); // 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); shaderParameters.WorldViewProjection = world * view * projection; shaderParameters.Diffuse = new Vector4(1, 1, 1, 1); context.UpdateSubresource(ref shaderParameters, shaderParameterBuffer); context.VertexShader.SetConstantBuffer(0, shaderParameterBuffer); context.PixelShader.SetConstantBuffer(0, shaderParameterBuffer); 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.Normal.Apply(context); context.Rasterizer.State = rasterizerState; context.OutputMerger.SetBlendState(blendState); context.OutputMerger.SetDepthStencilState(depthStencilState); context.PixelShader.SetSampler(0, samplerState); ratio = (float)ClientSize.Width / (float)ClientSize.Height; projection = Matrix.PerspectiveFovRH(3.14F / 3.0F, ratio, 0.01f, 1000); view = Matrix.Invert(head); world = Matrix.Translation(0, 0, -100.0f); worldViewProjection = world * view * projection; //context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.VertexShader.SetConstantBuffer(0, shaderParameterBuffer); context.PixelShader.SetConstantBuffer(0, shaderParameterBuffer); //Shapes.Cube.Begin(context); //Shapes.Cube.Draw(context); //Shapes.Sphere.Begin(context); //Shapes.Sphere.Draw(context); DrawPixels(worldViewProjection); // 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); shaderParameters.WorldViewProjection = world * view * projection; shaderParameters.Diffuse = new Vector4(1, 1, 1, 1); context.UpdateSubresource(ref shaderParameters, shaderParameterBuffer); context.VertexShader.SetConstantBuffer(0, shaderParameterBuffer); context.PixelShader.SetConstantBuffer(0, shaderParameterBuffer); context.DrawIndexed((int)controllerModels[controller].unTriangleCount * 3 * 4, 0, 0); } // Show Backbuffer swapChain.Present(0, PresentFlags.None); } } }
public abstract VROverlayError SetOverlayTextureBounds(ulong ulOverlayHandle,ref VRTextureBounds_t pOverlayTextureBounds);
void Update() { var overlay = OpenVR.Overlay; if (overlay == null) { return; } if (texture != null) { var error = overlay.ShowOverlay(handle); if (error == EVROverlayError.InvalidHandle || error == EVROverlayError.UnknownOverlay) { if (overlay.FindOverlay(key, ref handle) != EVROverlayError.None) { return; } } var tex = new Texture_t(); tex.handle = texture.GetNativeTexturePtr(); tex.eType = SteamVR.instance.textureType; tex.eColorSpace = EColorSpace.Auto; overlay.SetOverlayTexture(handle, ref tex); overlay.SetOverlayAlpha(handle, alpha); overlay.SetOverlayWidthInMeters(handle, scale); overlay.SetOverlayAutoCurveDistanceRangeInMeters(handle, curvedRange.x, curvedRange.y); var textureBounds = new VRTextureBounds_t(); textureBounds.uMin = (0 + uvOffset.x) * uvOffset.z; textureBounds.vMin = (1 + uvOffset.y) * uvOffset.w; textureBounds.uMax = (1 + uvOffset.x) * uvOffset.z; textureBounds.vMax = (0 + uvOffset.y) * uvOffset.w; overlay.SetOverlayTextureBounds(handle, ref textureBounds); var vecMouseScale = new HmdVector2_t(); vecMouseScale.v0 = mouseScale.x; vecMouseScale.v1 = mouseScale.y; overlay.SetOverlayMouseScale(handle, ref vecMouseScale); var vrcam = SteamVR_Render.Top(); if (vrcam != null && vrcam.origin != null) { var offset = new SteamVR_Utils.RigidTransform(vrcam.origin, transform); offset.pos.x /= vrcam.origin.localScale.x; offset.pos.y /= vrcam.origin.localScale.y; offset.pos.z /= vrcam.origin.localScale.z; offset.rot = vrcam.origin.rotation; offset.pos.z += distance; var t = offset.ToHmdMatrix34(); //overlay.SetOverlayTransformAbsolute(handle, SteamVR_Render.instance.trackingSpace, ref t); overlay.SetOverlayTransformTrackedDeviceRelative(handle, 0, ref t); } overlay.SetOverlayInputMethod(handle, inputMethod); if (curved || antialias) { highquality = true; } if (highquality) { overlay.SetHighQualityOverlay(handle); overlay.SetOverlayFlag(handle, VROverlayFlags.Curved, curved); overlay.SetOverlayFlag(handle, VROverlayFlags.RGSS4X, antialias); } else if (overlay.GetHighQualityOverlay() == handle) { overlay.SetHighQualityOverlay(OpenVR.k_ulOverlayHandleInvalid); } } else { overlay.HideOverlay(handle); } }