/// <summary> /// Helper to get a string from a tracked device property /// </summary> public static Result <string, ETrackedPropertyError> TrackedDeviceString(this CVRSystem hmd, int trackedDeviceIndex, ETrackedDeviceProperty prop) { if (hmd == null) { throw new ArgumentNullException(nameof(hmd)); } if (trackedDeviceIndex < 0 || trackedDeviceIndex > OpenVR.k_unMaxTrackedDeviceCount) { throw new ArgumentOutOfRangeException(nameof(trackedDeviceIndex)); } ETrackedPropertyError err = ETrackedPropertyError.TrackedProp_Success; uint requiredBufferLen = hmd.GetStringTrackedDeviceProperty((uint)trackedDeviceIndex, prop, null, 0, ref err); if (err != ETrackedPropertyError.TrackedProp_BufferTooSmall) { return(Result <string, ETrackedPropertyError> .Err(err)); } if (requiredBufferLen == 0) { return(""); } var pchBuffer = new StringBuilder((int)requiredBufferLen); requiredBufferLen = hmd.GetStringTrackedDeviceProperty((uint)trackedDeviceIndex, prop, pchBuffer, requiredBufferLen, ref err); if (err != ETrackedPropertyError.TrackedProp_Success) { return(Result <string, ETrackedPropertyError> .Err(err)); } return(pchBuffer.ToString()); }
// Token: 0x06000DDC RID: 3548 RVA: 0x00057EBC File Offset: 0x000560BC public void UpdateModel() { CVRSystem system = OpenVR.System; if (system == null) { return; } ETrackedPropertyError etrackedPropertyError = ETrackedPropertyError.TrackedProp_Success; uint stringTrackedDeviceProperty = system.GetStringTrackedDeviceProperty((uint)this.index, ETrackedDeviceProperty.Prop_RenderModelName_String, null, 0U, ref etrackedPropertyError); if (stringTrackedDeviceProperty <= 1U) { Debug.LogError("Failed to get render model name for tracked object " + this.index); return; } StringBuilder stringBuilder = new StringBuilder((int)stringTrackedDeviceProperty); system.GetStringTrackedDeviceProperty((uint)this.index, ETrackedDeviceProperty.Prop_RenderModelName_String, stringBuilder, stringTrackedDeviceProperty, ref etrackedPropertyError); string text = stringBuilder.ToString(); if (this.renderModelName != text) { this.renderModelName = text; base.StartCoroutine(this.SetModelAsync(text)); } }
private string QueryDeviceStringProperty(CVRSystem system, uint deviceIndex, ETrackedDeviceProperty prop) { var error = default(ETrackedPropertyError); var capacity = (int)system.GetStringTrackedDeviceProperty(deviceIndex, prop, null, 0, ref error); if (capacity <= 1 || capacity > 128) { return(string.Empty); } if (m_sb == null) { m_sb = new StringBuilder(capacity); } else { m_sb.EnsureCapacity(capacity); } system.GetStringTrackedDeviceProperty(deviceIndex, prop, m_sb, (uint)m_sb.Capacity, ref error); if (error != ETrackedPropertyError.TrackedProp_Success) { return(string.Empty); } var result = m_sb.ToString(); m_sb.Length = 0; return(result); }
string GetStringProperty(ETrackedDeviceProperty prop) { var error = ETrackedPropertyError.TrackedProp_Success; var capactiy = vr.GetStringTrackedDeviceProperty(this.index, prop, null, 0, ref error); if (capactiy > 1) { var result = new System.Text.StringBuilder((int)capactiy); vr.GetStringTrackedDeviceProperty(this.index, prop, result, capactiy, ref error); return(result.ToString()); } return((error != ETrackedPropertyError.TrackedProp_Success) ? error.ToString() : "<unknown>"); }
private string GetStringProperty(ETrackedDeviceProperty prop) { var error = ETrackedPropertyError.TrackedProp_Success; var capactiy = hmd.GetStringTrackedDeviceProperty(OpenVR.k_unTrackedDeviceIndex_Hmd, prop, null, 0, ref error); if (capactiy > 1) { var result = new System.Text.StringBuilder((int)capactiy); hmd.GetStringTrackedDeviceProperty(OpenVR.k_unTrackedDeviceIndex_Hmd, prop, result, capactiy, ref error); return(result.ToString()); } return((error != ETrackedPropertyError.TrackedProp_Success) ? error.ToString() : "<unknown>"); }
public static string GetTrackedDeviceManufacturerString(uint deviceId) { CVRSystem hmd = SteamVR.instance.hmd; var error = ETrackedPropertyError.TrackedProp_Success; var capacity = hmd.GetStringTrackedDeviceProperty(deviceId, ETrackedDeviceProperty.Prop_ManufacturerName_String, null, 0, ref error); if (capacity > 1) { var result = new System.Text.StringBuilder((int)capacity); hmd.GetStringTrackedDeviceProperty(deviceId, ETrackedDeviceProperty.Prop_ManufacturerName_String, result, capacity, ref error); return(result.ToString()); } return(null); }
public static string GetStringTrackedDeviceProperty(this CVRSystem system, uint unDeviceIndex, ETrackedDeviceProperty prop) { ETrackedPropertyError error = ETrackedPropertyError.TrackedProp_Success; uint length = system.GetStringTrackedDeviceProperty(unDeviceIndex, prop, null, 0, ref error); StringBuilder builder = new StringBuilder((int)length); system.GetStringTrackedDeviceProperty(unDeviceIndex, prop, builder, length, ref error); if (error != ETrackedPropertyError.TrackedProp_Success) { throw OpenVRException.Make(error); } return(builder.ToString()); }
public string GetTrackedDeviceString(uint deviceIndex, ETrackedDeviceProperty prop) { var error = ETrackedPropertyError.TrackedProp_Success; var bufferSize = m_System.GetStringTrackedDeviceProperty(deviceIndex, prop, null, 0, ref error); if (bufferSize == 0) { return(string.Empty); } var buffer = new System.Text.StringBuilder((int)bufferSize); bufferSize = m_System.GetStringTrackedDeviceProperty(deviceIndex, prop, buffer, bufferSize, ref error); return(buffer.ToString()); }
/// <summary> /// Internal start call for VR setup. /// </summary> public void Start() { uint w = 0; uint h = 0; VR.GetRecommendedRenderTargetSize(ref w, ref h); if (w <= 0 || h <= 0) { throw new Exception("Failed to start VR: Invalid render target size!"); } w *= 2; TheClient.Engine3D.MainView.Generate(TheClient.Engine3D, (int)w, (int)h); TheClient.Engine3D.MainView.GenerateFBO(); StringBuilder val = new StringBuilder(256); ETrackedPropertyError errx = ETrackedPropertyError.TrackedProp_Success; VR.GetStringTrackedDeviceProperty(OpenVR.k_unTrackedDeviceIndex_Hmd, ETrackedDeviceProperty.Prop_TrackingSystemName_String, val, 256, ref errx); SysConsole.Output(OutputType.INIT, "Switching to VR mode: " + w + "/" + h + "... " + val.ToString()); VRModel = val.ToString(); Compositor = OpenVR.Compositor; Compositor.SetTrackingSpace(ETrackingUniverseOrigin.TrackingUniverseStanding); Compositor.CompositorBringToFront(); LeftTexture = new VRControllerTextureEngine(); RightTexture = new VRControllerTextureEngine(); LeftTexture.BaseTexture = TheClient.Textures.GetTexture("vr/controller/vive_circle_left"); RightTexture.BaseTexture = TheClient.Textures.GetTexture("vr/controller/vive_circle_right"); LeftTexture.GenerateFirst(); RightTexture.GenerateFirst(); RightControllerModel = TheClient.Models.GetModel("vr/controller/vive"); LeftControllerModel = TheClient.Models.GetModel("vr/controller/vive"); }
/// <summary>Interrogate OpenVR about a property in the device property Json file. By default we are interested in the Model Number.</summary> /// <param name="deviceIndex">Used by OpenVR to identify any tracked device, from the HMD to controllers and Lighthouses.</param> /// <param name="trackedDeviceProperty">The property to retrieve from the device property Json file.</param> /// <returns> If it exists, a string matching the value of the property in the property Json file of the device.</returns> public static string GetControllerProperty(int deviceIndex, ETrackedDeviceProperty trackedDeviceProperty) { var stringBuilder = new StringBuilder(1000); ETrackedPropertyError trackedPropertyError = ETrackedPropertyError.TrackedProp_Success; CVRSystem system = OpenVR.System; system.GetStringTrackedDeviceProperty((uint)deviceIndex, trackedDeviceProperty, stringBuilder, 1000, ref trackedPropertyError); return(stringBuilder.ToString()); }
string GetStringProperty(CVRSystem system, uint deviceId, ETrackedDeviceProperty prop) { var error = ETrackedPropertyError.TrackedProp_Success; var result = new System.Text.StringBuilder(); var capacity = system.GetStringTrackedDeviceProperty(deviceId, prop, result, 64, ref error); if (capacity > 0) return result.ToString(); return string.Empty; }
//device情報を取得する public bool GetPropertyString(uint idx, ETrackedDeviceProperty prop, out string result) { result = null; ETrackedPropertyError error = new ETrackedPropertyError(); //device情報を取得するのに必要な文字数を取得 uint size = openvr.GetStringTrackedDeviceProperty(idx, prop, null, 0, ref error); if (error != ETrackedPropertyError.TrackedProp_BufferTooSmall) { return(false); } StringBuilder s = new StringBuilder((int)size); s.Length = (int)size; //文字長さ確保 //device情報を取得する openvr.GetStringTrackedDeviceProperty(idx, prop, s, size, ref error); result = s.ToString(); return(error == ETrackedPropertyError.TrackedProp_Success); }
static string getTrackedDeviceString(ETrackedDeviceProperty prop) { var error = ETrackedPropertyError.TrackedProp_Success; uint bufferLength = vrSystem.GetStringTrackedDeviceProperty(OpenVR.k_unTrackedDeviceIndex_Hmd, prop, null, 0, ref error); if (bufferLength > 1) { var stringBuilder = new System.Text.StringBuilder((int)bufferLength); vrSystem.GetStringTrackedDeviceProperty(OpenVR.k_unTrackedDeviceIndex_Hmd, prop, stringBuilder, bufferLength, ref error); return(stringBuilder.ToString()); } if (error != ETrackedPropertyError.TrackedProp_Success) { return(error.ToString()); } return("unkown"); }
public string GetTrackedDevicePropertyString(uint index, ETrackedDeviceProperty property) { var sb = new StringBuilder(); var error = new ETrackedPropertyError(); uint succeeded = _vr_system.GetStringTrackedDeviceProperty(index, property, sb, (uint)sb.Capacity, ref error); if (error == ETrackedPropertyError.TrackedProp_Success) { return(sb.ToString()); } return(null); }
public static string GetControllerProperty(int deviceIndex, ETrackedDeviceProperty p) { var sbType = new StringBuilder(1000); ETrackedPropertyError err = ETrackedPropertyError.TrackedProp_Success; CVRSystem system = OpenVR.System; if (system == null) { return("SteamVR not yet initialized"); } system.GetStringTrackedDeviceProperty((uint)deviceIndex, p, sbType, 1000, ref err); return(sbType.ToString()); }
private string _GetTrackerSerialNumber(uint pTrackerIndex) { string sn = ""; ETrackedPropertyError error = new ETrackedPropertyError(); StringBuilder sb = new StringBuilder(); _cvrSystem.GetStringTrackedDeviceProperty(pTrackerIndex, ETrackedDeviceProperty.Prop_SerialNumber_String, sb, OpenVR.k_unMaxPropertyStringSize, ref error); if (error == ETrackedPropertyError.TrackedProp_Success) { sn = sb.ToString(); } return(sn); }
private string GetDevicePropertyString(uint deviceId, ETrackedDeviceProperty prop, uint capacity) { ETrackedPropertyError error = ETrackedPropertyError.TrackedProp_UnknownProperty; System.Text.StringBuilder strBuilder = new System.Text.StringBuilder((int)capacity); _vrSystem.GetStringTrackedDeviceProperty(deviceId, prop, strBuilder, capacity, ref error); if (error == ETrackedPropertyError.TrackedProp_Success) { return(strBuilder.ToString().Trim()); } return(""); }
string GetSerial(int i) { var error = ETrackedPropertyError.TrackedProp_Success; FSerialBuilder.Clear(); FSystem.GetStringTrackedDeviceProperty((uint)i, ETrackedDeviceProperty.Prop_SerialNumber_String, FSerialBuilder, CSerialBuilderSize, ref error); if (error == ETrackedPropertyError.TrackedProp_Success) { return(FSerialBuilder.ToString()); } else { return(""); } }
//device情報を取得する private string GetProperty(uint idx, ETrackedDeviceProperty prop) { #pragma warning disable 0219 string Tag = "[" + this.GetType().Name + ":" + System.Reflection.MethodBase.GetCurrentMethod(); //クラス名とメソッド名を自動取得 #pragma warning restore 0219 ETrackedPropertyError error = new ETrackedPropertyError(); //device情報を取得するのに必要な文字数を取得 uint size = openvr.GetStringTrackedDeviceProperty(idx, prop, null, 0, ref error); if (error != ETrackedPropertyError.TrackedProp_BufferTooSmall) { return(null); } StringBuilder s = new StringBuilder(); s.Length = (int)size; //文字長さ確保 //device情報を取得する openvr.GetStringTrackedDeviceProperty(idx, prop, s, size, ref error); if (error != ETrackedPropertyError.TrackedProp_Success) { return(null); } return(s.ToString()); }
public override void Initialize(GraphicsDevice gd) { _gd = gd; StringBuilder sb = new StringBuilder(512); ETrackedPropertyError error = ETrackedPropertyError.TrackedProp_Success; uint ret = _vrSystem.GetStringTrackedDeviceProperty( OVR.k_unTrackedDeviceIndex_Hmd, ETrackedDeviceProperty.Prop_TrackingSystemName_String, sb, 512u, ref error); if (error != ETrackedPropertyError.TrackedProp_Success) { _deviceName = "<Unknown OpenVR Device>"; } else { _deviceName = sb.ToString(); } uint eyeWidth = 0; uint eyeHeight = 0; _vrSystem.GetRecommendedRenderTargetSize(ref eyeWidth, ref eyeHeight); _leftEyeFB = CreateFramebuffer(eyeWidth, eyeHeight); _rightEyeFB = CreateFramebuffer(eyeWidth, eyeHeight); Matrix4x4 eyeToHeadLeft = ToSysMatrix(_vrSystem.GetEyeToHeadTransform(EVREye.Eye_Left)); Matrix4x4.Invert(eyeToHeadLeft, out _headToEyeLeft); Matrix4x4 eyeToHeadRight = ToSysMatrix(_vrSystem.GetEyeToHeadTransform(EVREye.Eye_Right)); Matrix4x4.Invert(eyeToHeadRight, out _headToEyeRight); _projLeft = ToSysMatrix(_vrSystem.GetProjectionMatrix(EVREye.Eye_Left, 0.1f, 1000f)); _projRight = ToSysMatrix(_vrSystem.GetProjectionMatrix(EVREye.Eye_Right, 0.1f, 1000f)); }
public override void Initialize() { StringBuilder sb = new StringBuilder(512); ETrackedPropertyError error = ETrackedPropertyError.TrackedProp_Success; uint ret = _vrSystem.GetStringTrackedDeviceProperty( OVR.k_unTrackedDeviceIndex_Hmd, ETrackedDeviceProperty.Prop_TrackingSystemName_String, sb, 512u, ref error); if (error != ETrackedPropertyError.TrackedProp_Success) { _deviceName = "<Unknown OpenVR Device>"; } else { _deviceName = sb.ToString(); } uint eyeWidth = 0; uint eyeHeight = 0; _vrSystem.GetRecommendedRenderTargetSize(ref eyeWidth, ref eyeHeight); _leftEyeGT = GPUDevice.CreateTexture(); var descLeftEye = GPUTextureDescription.New2D((int)eyeWidth, (int)eyeHeight, 1, PixelFormat.R8G8B8A8_UNorm, msaaLevel: _options.EyeRenderTargetSampleCount); _leftEyeGT.Init(ref descLeftEye); _rightEyeGT = GPUDevice.CreateTexture(); var descRightEye = GPUTextureDescription.New2D((int)eyeWidth, (int)eyeHeight, 1, PixelFormat.R8G8B8A8_UNorm, msaaLevel: _options.EyeRenderTargetSampleCount); _rightEyeGT.Init(ref descRightEye); Matrix eyeToHeadLeft = ToSysMatrix(_vrSystem.GetEyeToHeadTransform(EVREye.Eye_Left)); Matrix.Invert(ref eyeToHeadLeft, out _headToEyeLeft); Matrix eyeToHeadRight = ToSysMatrix(_vrSystem.GetEyeToHeadTransform(EVREye.Eye_Right)); Matrix.Invert(ref eyeToHeadRight, out _headToEyeRight); // Default RH matrices /*_projLeft = ToSysMatrix(_vrSystem.GetProjectionMatrix(EVREye.Eye_Left, 0.1f, 10000f)); * _projRight = ToSysMatrix(_vrSystem.GetProjectionMatrix(EVREye.Eye_Right, 0.1f, 10000f));*/ // Build LH projection matrices (https://github.com/ValveSoftware/openvr/wiki/IVRSystem::GetProjectionRaw) float pLeft = 0; float pRight = 0; float pTop = 0; float pBottom = 0; // Default values float zNear = 0.1f; float zFar = 20000f; _vrSystem.GetProjectionRaw(EVREye.Eye_Left, ref pLeft, ref pRight, ref pTop, ref pBottom); _projLeft = Matrix.PerspectiveOffCenter(pLeft * zNear, pRight * zNear, pBottom * zNear * -1f, pTop * zNear * -1f, zNear, zFar); _vrSystem.GetProjectionRaw(EVREye.Eye_Right, ref pLeft, ref pRight, ref pTop, ref pBottom); _projRight = Matrix.PerspectiveOffCenter(pLeft * zNear, pRight * zNear, pBottom * zNear * -1f, pTop * zNear * -1f, zNear, zFar); }
internal static void Enable() { var initError = EVRInitError.None; System = OpenVR.Init(ref initError); if (initError != EVRInitError.None) { return; } Compositor = OpenVR.Compositor; Compositor.CompositorBringToFront(); Compositor.FadeGrid(5.0f, false); var count = OpenVR.k_unMaxTrackedDeviceCount; CurrentPoses = new TrackedDevicePose_t[count]; NextPoses = new TrackedDevicePose_t[count]; Controllers = new List <uint>(); ControllerModels = new RenderModel_t[count]; ControllerTextures = new RenderModel_TextureMap_t[count]; ControllerTextureViews = new ShaderResourceView[count]; ControllerVertexBuffers = new SharpDX.Direct3D11.Buffer[count]; ControllerIndexBuffers = new SharpDX.Direct3D11.Buffer[count]; ControllerVertexBufferBindings = new VertexBufferBinding[count]; ControllerEmitters = new Emitter[count]; ControllerVoices = new SourceVoice[count]; for (uint device = 0; device < count; device++) { var deviceClass = System.GetTrackedDeviceClass(device); switch (deviceClass) { case ETrackedDeviceClass.HMD: Headset = device; break; case ETrackedDeviceClass.Controller: Controllers.Add(device); break; } } uint width = 0; uint height = 0; System.GetRecommendedRenderTargetSize(ref width, ref height); headsetSize = new Size((int)width, (int)height); windowSize = new Size(960, 540); var leftEyeProjection = Convert(System.GetProjectionMatrix(EVREye.Eye_Left, 0.01f, 1000.0f)); var rightEyeProjection = Convert(System.GetProjectionMatrix(EVREye.Eye_Right, 0.01f, 1000.0f)); var leftEyeView = Convert(System.GetEyeToHeadTransform(EVREye.Eye_Left)); var rightEyeView = Convert(System.GetEyeToHeadTransform(EVREye.Eye_Right)); foreach (var controller in Controllers) { var modelName = new StringBuilder(255, 255); var propertyError = ETrackedPropertyError.TrackedProp_Success; var length = System.GetStringTrackedDeviceProperty(controller, ETrackedDeviceProperty.Prop_RenderModelName_String, modelName, 255, ref propertyError); if (propertyError == ETrackedPropertyError.TrackedProp_Success) { var modelName2 = modelName.ToString(); while (true) { var pointer = IntPtr.Zero; var modelError = EVRRenderModelError.None; modelError = OpenVR.RenderModels.LoadRenderModel_Async(modelName2, ref pointer); if (modelError == EVRRenderModelError.Loading) { continue; } if (modelError == EVRRenderModelError.None) { var renderModel = global::System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_t>(pointer); ControllerModels[controller] = renderModel; break; } } while (true) { var pointer = IntPtr.Zero; var textureError = EVRRenderModelError.None; textureError = OpenVR.RenderModels.LoadTexture_Async(ControllerModels[controller].diffuseTextureId, ref pointer); if (textureError == EVRRenderModelError.Loading) { continue; } if (textureError == EVRRenderModelError.None) { var texture = global::System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_TextureMap_t>(pointer); ControllerTextures[controller] = texture; break; } } } } int adapterIndex = 0; System.GetDXGIOutputInfo(ref adapterIndex); Thread = new Thread(Run); Thread.Start(); }
static void Main() { var initError = EVRInitError.None; system = OpenVR.Init(ref initError); if (initError != EVRInitError.None) { return; } compositor = OpenVR.Compositor; compositor.CompositorBringToFront(); compositor.FadeGrid(5.0f, false); count = OpenVR.k_unMaxTrackedDeviceCount; currentPoses = new TrackedDevicePose_t[count]; nextPoses = new TrackedDevicePose_t[count]; controllers = new List <uint>(); controllerModels = new RenderModel_t[count]; controllerTextures = new RenderModel_TextureMap_t[count]; controllerTextureViews = new ShaderResourceView[count]; controllerVertexBuffers = new SharpDX.Direct3D11.Buffer[count]; controllerIndexBuffers = new SharpDX.Direct3D11.Buffer[count]; controllerVertexBufferBindings = new VertexBufferBinding[count]; for (uint device = 0; device < count; device++) { var deviceClass = system.GetTrackedDeviceClass(device); switch (deviceClass) { case ETrackedDeviceClass.HMD: headset = device; break; case ETrackedDeviceClass.Controller: controllers.Add(device); break; } } uint width = 0; uint height = 0; system.GetRecommendedRenderTargetSize(ref width, ref height); headsetSize = new Size((int)width, (int)height); windowSize = new Size(960, 540); var leftEyeProjection = Convert(system.GetProjectionMatrix(EVREye.Eye_Left, 0.01f, 1000.0f)); var rightEyeProjection = Convert(system.GetProjectionMatrix(EVREye.Eye_Right, 0.01f, 1000.0f)); var leftEyeView = Convert(system.GetEyeToHeadTransform(EVREye.Eye_Left)); var rightEyeView = Convert(system.GetEyeToHeadTransform(EVREye.Eye_Right)); foreach (var controller in controllers) { var modelName = new StringBuilder(255, 255); var propertyError = ETrackedPropertyError.TrackedProp_Success; var length = system.GetStringTrackedDeviceProperty(controller, ETrackedDeviceProperty.Prop_RenderModelName_String, modelName, 255, ref propertyError); if (propertyError == ETrackedPropertyError.TrackedProp_Success) { var modelName2 = modelName.ToString(); while (true) { var pointer = IntPtr.Zero; var modelError = EVRRenderModelError.None; modelError = OpenVR.RenderModels.LoadRenderModel_Async(modelName2, ref pointer); if (modelError == EVRRenderModelError.Loading) { continue; } if (modelError == EVRRenderModelError.None) { var renderModel = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_t>(pointer); controllerModels[controller] = renderModel; break; } } while (true) { var pointer = IntPtr.Zero; var textureError = EVRRenderModelError.None; textureError = OpenVR.RenderModels.LoadTexture_Async(controllerModels[controller].diffuseTextureId, ref pointer); if (textureError == EVRRenderModelError.Loading) { continue; } if (textureError == EVRRenderModelError.None) { var texture = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_TextureMap_t>(pointer); controllerTextures[controller] = texture; break; } } } } int adapterIndex = 0; system.GetDXGIOutputInfo(ref adapterIndex); using (var form = new Form()) using (var factory = new Factory4()) { form.ClientSize = windowSize; var adapter = factory.GetAdapter(adapterIndex); var swapChainDescription = new SwapChainDescription { BufferCount = 1, Flags = SwapChainFlags.None, IsWindowed = true, ModeDescription = new ModeDescription { Format = Format.B8G8R8A8_UNorm, Width = form.ClientSize.Width, Height = form.ClientSize.Height, RefreshRate = new Rational(60, 1) }, OutputHandle = form.Handle, SampleDescription = new SampleDescription(1, 0), SwapEffect = SwapEffect.Discard, Usage = Usage.RenderTargetOutput }; SharpDX.Direct3D11.Device.CreateWithSwapChain(adapter, DeviceCreationFlags.None, swapChainDescription, out device, out swapChain); factory.MakeWindowAssociation(form.Handle, WindowAssociationFlags.None); context = device.ImmediateContext; using (var backBuffer = swapChain.GetBackBuffer <Texture2D>(0)) backBufferView = new RenderTargetView(device, backBuffer); var depthBufferDescription = new Texture2DDescription { Format = Format.D16_UNorm, ArraySize = 1, MipLevels = 1, Width = form.ClientSize.Width, Height = form.ClientSize.Height, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default, BindFlags = BindFlags.DepthStencil, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.None }; using (var depthBuffer = new Texture2D(device, depthBufferDescription)) depthStencilView = new DepthStencilView(device, depthBuffer); // Create Eye Textures var eyeTextureDescription = new Texture2DDescription { ArraySize = 1, BindFlags = BindFlags.RenderTarget, CpuAccessFlags = CpuAccessFlags.None, Format = Format.B8G8R8A8_UNorm, Width = headsetSize.Width, Height = headsetSize.Height, MipLevels = 1, OptionFlags = ResourceOptionFlags.None, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default }; var leftEyeTexture = new Texture2D(device, eyeTextureDescription); var rightEyeTexture = new Texture2D(device, eyeTextureDescription); var leftEyeTextureView = new RenderTargetView(device, leftEyeTexture); var rightEyeTextureView = new RenderTargetView(device, rightEyeTexture); // Create Eye Depth Buffer eyeTextureDescription.BindFlags = BindFlags.DepthStencil; eyeTextureDescription.Format = Format.D32_Float; var eyeDepth = new Texture2D(device, eyeTextureDescription); var eyeDepthView = new DepthStencilView(device, eyeDepth); Shapes.Cube.Load(device); Shapes.Sphere.Load(device); Shaders.Position.Load(device); Shaders.Normal.Load(device); Shaders.NormalTexture.Load(device); // Load Controller Models foreach (var controller in controllers) { var model = controllerModels[controller]; controllerVertexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rVertexData, new BufferDescription { BindFlags = BindFlags.VertexBuffer, SizeInBytes = (int)model.unVertexCount * 32 }); controllerVertexBufferBindings[controller] = new VertexBufferBinding(controllerVertexBuffers[controller], 32, 0); controllerIndexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rIndexData, new BufferDescription { BindFlags = BindFlags.IndexBuffer, SizeInBytes = (int)model.unTriangleCount * 3 * 2 }); var texture = controllerTextures[controller]; using (var texture2d = new Texture2D(device, new Texture2DDescription { ArraySize = 1, BindFlags = BindFlags.ShaderResource, Format = Format.R8G8B8A8_UNorm, Width = texture.unWidth, Height = texture.unHeight, MipLevels = 1, SampleDescription = new SampleDescription(1, 0) }, new DataRectangle(texture.rubTextureMapData, texture.unWidth * 4))) controllerTextureViews[controller] = new ShaderResourceView(device, texture2d); } worldViewProjectionBuffer = new SharpDX.Direct3D11.Buffer(device, Utilities.SizeOf <Matrix>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0); var rasterizerStateDescription = RasterizerStateDescription.Default(); //rasterizerStateDescription.FillMode = FillMode.Wireframe; rasterizerStateDescription.IsFrontCounterClockwise = true; //rasterizerStateDescription.CullMode = CullMode.None; rasterizerState = new RasterizerState(device, rasterizerStateDescription); var blendStateDescription = BlendStateDescription.Default(); blendStateDescription.RenderTarget[0].BlendOperation = BlendOperation.Add; blendStateDescription.RenderTarget[0].SourceBlend = BlendOption.SourceAlpha; blendStateDescription.RenderTarget[0].DestinationBlend = BlendOption.InverseSourceAlpha; blendStateDescription.RenderTarget[0].IsBlendEnabled = false; blendState = new BlendState(device, blendStateDescription); var depthStateDescription = DepthStencilStateDescription.Default(); depthStateDescription.DepthComparison = Comparison.LessEqual; depthStateDescription.IsDepthEnabled = true; depthStateDescription.IsStencilEnabled = false; depthStencilState = new DepthStencilState(device, depthStateDescription); var samplerStateDescription = SamplerStateDescription.Default(); samplerStateDescription.Filter = Filter.MinMagMipLinear; samplerStateDescription.AddressU = TextureAddressMode.Wrap; samplerStateDescription.AddressV = TextureAddressMode.Wrap; samplerState = new SamplerState(device, samplerStateDescription); startTime = DateTime.Now; frame = 0; windowSize = form.ClientSize; backgroundColor = new RawColor4(0.1f, 0.1f, 0.1f, 1); var vrEvent = new VREvent_t(); var eventSize = (uint)Utilities.SizeOf <VREvent_t>(); head = Matrix.Identity; // Initialize Audio var audioSamples = 1024; var audioDevices = DirectSoundCapture.GetDevices(); //var audioCapture = new DirectSoundCapture(devices.OrderByDescending(d => d.Description.Contains("Mic")).First().DriverGuid); var audioCapture = new DirectSoundCapture(audioDevices.OrderByDescending(d => d.Description.Contains("Mix")).First().DriverGuid); var audioFormat = new WaveFormat(); var audioLength = audioFormat.ConvertLatencyToByteSize(24); var audioData = new byte[audioLength]; var audioPosition = 0; var leftWaveForm = new float[1024 * 8]; var rightWaveForm = new float[1024 * 8]; for (var sample = 0; sample < 1024; sample++) { leftWaveForm[(sample * 8) + 0] = -1.0f + ((float)sample / 512.0f); rightWaveForm[(sample * 8) + 0] = -1.0f + ((float)sample / 512.0f); } var audioBuffer = new CaptureBuffer(audioCapture, new CaptureBufferDescription { BufferBytes = audioLength, Format = audioFormat }); audioBuffer.Start(true); var waveFormBufferDescription = new BufferDescription { BindFlags = BindFlags.VertexBuffer, SizeInBytes = leftWaveForm.Length * sizeof(float), CpuAccessFlags = CpuAccessFlags.Write, Usage = ResourceUsage.Dynamic }; var leftWaveFormVertexBuffer = SharpDX.Direct3D11.Buffer.Create(device, leftWaveForm, waveFormBufferDescription); var rightWaveFormVertexBuffer = SharpDX.Direct3D11.Buffer.Create(device, rightWaveForm, waveFormBufferDescription); var leftWaveFormVertexBufferBinding = new VertexBufferBinding(leftWaveFormVertexBuffer, 8 * sizeof(float), 0); var rightWaveFormVertexBufferBinding = new VertexBufferBinding(rightWaveFormVertexBuffer, 8 * sizeof(float), 0); RenderLoop.Run(form, () => { if (audioBuffer.CurrentCapturePosition != audioBuffer.CurrentRealPosition) { audioBuffer.Read(audioData, 0, audioData.Length, 0, LockFlags.None); for (var sample = 0; sample < 1024; sample++) { leftWaveForm[(sample * 8) + 1] = -BitConverter.ToInt16(audioData, sample * 4) / (float)short.MinValue; rightWaveForm[(sample * 8) + 1] = -BitConverter.ToInt16(audioData, (sample * 4) + 2) / (float)short.MinValue; } DataStream stream; context.MapSubresource(leftWaveFormVertexBuffer, 0, MapMode.WriteDiscard, SharpDX.Direct3D11.MapFlags.None, out stream); stream.WriteRange(leftWaveForm); context.UnmapSubresource(leftWaveFormVertexBuffer, 0); stream.Dispose(); context.MapSubresource(rightWaveFormVertexBuffer, 0, MapMode.WriteDiscard, SharpDX.Direct3D11.MapFlags.None, out stream); stream.WriteRange(rightWaveForm); context.UnmapSubresource(rightWaveFormVertexBuffer, 0); stream.Dispose(); } audioPosition += 8; if (audioPosition >= leftWaveForm.Length) { audioPosition = 0; } while (system.PollNextEvent(ref vrEvent, eventSize)) { switch ((EVREventType)vrEvent.eventType) { case EVREventType.VREvent_TrackedDeviceActivated: var controller = vrEvent.trackedDeviceIndex; controllers.Add(controller); var modelName = new StringBuilder(255, 255); var propertyError = ETrackedPropertyError.TrackedProp_Success; var length = system.GetStringTrackedDeviceProperty(controller, ETrackedDeviceProperty.Prop_RenderModelName_String, modelName, 255, ref propertyError); if (propertyError == ETrackedPropertyError.TrackedProp_Success) { var modelName2 = modelName.ToString(); while (true) { var pointer = IntPtr.Zero; var modelError = EVRRenderModelError.None; modelError = OpenVR.RenderModels.LoadRenderModel_Async(modelName2, ref pointer); if (modelError == EVRRenderModelError.Loading) { continue; } if (modelError == EVRRenderModelError.None) { var renderModel = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_t>(pointer); controllerModels[controller] = renderModel; // Load Controller Model var model = controllerModels[controller]; controllerVertexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rVertexData, new BufferDescription { BindFlags = BindFlags.VertexBuffer, SizeInBytes = (int)model.unVertexCount * 32 }); controllerVertexBufferBindings[controller] = new VertexBufferBinding(controllerVertexBuffers[controller], 32, 0); controllerIndexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rIndexData, new BufferDescription { BindFlags = BindFlags.IndexBuffer, SizeInBytes = (int)model.unTriangleCount * 3 * 2 }); break; } } while (true) { var pointer = IntPtr.Zero; var textureError = EVRRenderModelError.None; textureError = OpenVR.RenderModels.LoadTexture_Async(controllerModels[controller].diffuseTextureId, ref pointer); if (textureError == EVRRenderModelError.Loading) { continue; } if (textureError == EVRRenderModelError.None) { var textureMap = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_TextureMap_t>(pointer); controllerTextures[controller] = textureMap; using (var texture2d = new Texture2D(device, new Texture2DDescription { ArraySize = 1, BindFlags = BindFlags.ShaderResource, Format = Format.R8G8B8A8_UNorm, Width = textureMap.unWidth, Height = textureMap.unHeight, MipLevels = 1, SampleDescription = new SampleDescription(1, 0) }, new DataRectangle(textureMap.rubTextureMapData, textureMap.unWidth * 4))) controllerTextureViews[controller] = new ShaderResourceView(device, texture2d); break; } } } break; case EVREventType.VREvent_TrackedDeviceDeactivated: controllers.RemoveAll(c => c == vrEvent.trackedDeviceIndex); break; default: System.Diagnostics.Debug.WriteLine((EVREventType)vrEvent.eventType); break; } } if (form.ClientSize != windowSize) { Utilities.Dispose(ref backBufferView); if (form.ClientSize.Width != 0 && form.ClientSize.Height != 0) { swapChain.ResizeBuffers(1, form.ClientSize.Width, form.ClientSize.Height, Format.B8G8R8A8_UNorm, SwapChainFlags.None); using (var backBuffer = swapChain.GetBackBuffer <Texture2D>(0)) backBufferView = new RenderTargetView(device, backBuffer); } windowSize = form.ClientSize; } // Update Device Tracking compositor.WaitGetPoses(currentPoses, nextPoses); if (currentPoses[headset].bPoseIsValid) { Convert(ref currentPoses[headset].mDeviceToAbsoluteTracking, ref head); } foreach (var controller in controllers) { var controllerMatrix = Matrix.Identity; Convert(ref currentPoses[controller].mDeviceToAbsoluteTracking, ref controllerMatrix); } // Render Left Eye context.Rasterizer.SetViewport(0, 0, headsetSize.Width, headsetSize.Height); context.OutputMerger.SetTargets(eyeDepthView, leftEyeTextureView); context.OutputMerger.SetDepthStencilState(depthStencilState); context.ClearRenderTargetView(leftEyeTextureView, backgroundColor); context.ClearDepthStencilView(eyeDepthView, DepthStencilClearFlags.Depth, 1.0f, 0); Shaders.Normal.Apply(context); context.Rasterizer.State = rasterizerState; context.OutputMerger.SetBlendState(blendState); context.OutputMerger.SetDepthStencilState(depthStencilState); context.PixelShader.SetSampler(0, samplerState); var ratio = (float)headsetSize.Width / (float)headsetSize.Height; var projection = leftEyeProjection; var view = Matrix.Invert(leftEyeView * head); var world = Matrix.Scaling(1.0f + (Math.Abs(leftWaveForm[audioPosition + 1]) * 0.1f)) * Matrix.Translation(0, 1.0f, 0); worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer); //Shapes.Cube.Begin(context); //Shapes.Cube.Draw(context); Shapes.Sphere.Begin(context); Shapes.Sphere.Draw(context); // Draw Controllers context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; Shaders.NormalTexture.Apply(context); context.PixelShader.SetSampler(0, samplerState); foreach (var controller in controllers) { context.InputAssembler.SetVertexBuffers(0, controllerVertexBufferBindings[controller]); context.InputAssembler.SetIndexBuffer(controllerIndexBuffers[controller], Format.R16_UInt, 0); context.PixelShader.SetShaderResource(0, controllerTextureViews[controller]); Convert(ref currentPoses[controller].mDeviceToAbsoluteTracking, ref world); world = Matrix.Scaling(1.0f + (Math.Abs(leftWaveForm[audioPosition + 1]) * 0.5f)) * world; worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer); context.DrawIndexed((int)controllerModels[controller].unTriangleCount * 3 * 4, 0, 0); } // Draw Waveforms Shaders.Position.Apply(context); world = Matrix.Scaling(100, 2.5f, 1) * Matrix.Translation(0, 1, 1); worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.InputAssembler.PrimitiveTopology = PrimitiveTopology.LineStrip; context.InputAssembler.SetVertexBuffers(0, leftWaveFormVertexBufferBinding); context.Draw(1024, 0); world = Matrix.Scaling(100, 2.5f, 1) * Matrix.Translation(0, 1, -1); worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.InputAssembler.SetVertexBuffers(0, rightWaveFormVertexBufferBinding); context.Draw(1024, 0); // Present Left Eye var texture = new Texture_t { eType = ETextureType.DirectX, eColorSpace = EColorSpace.Gamma, handle = leftEyeTextureView.Resource.NativePointer }; var bounds = new VRTextureBounds_t { uMin = 0.0f, uMax = 1.0f, vMin = 0.0f, vMax = 1.0f, }; var submitError = compositor.Submit(EVREye.Eye_Left, ref texture, ref bounds, EVRSubmitFlags.Submit_Default); if (submitError != EVRCompositorError.None) { System.Diagnostics.Debug.WriteLine(submitError); } // Render Right Eye context.Rasterizer.SetViewport(0, 0, headsetSize.Width, headsetSize.Height); context.OutputMerger.SetTargets(eyeDepthView, rightEyeTextureView); context.OutputMerger.SetDepthStencilState(depthStencilState); context.ClearRenderTargetView(rightEyeTextureView, backgroundColor); context.ClearDepthStencilView(eyeDepthView, DepthStencilClearFlags.Depth, 1.0f, 0); Shaders.Normal.Apply(context); context.Rasterizer.State = rasterizerState; context.OutputMerger.SetBlendState(blendState); context.OutputMerger.SetDepthStencilState(depthStencilState); context.PixelShader.SetSampler(0, samplerState); projection = rightEyeProjection; view = Matrix.Invert(rightEyeView * head); world = Matrix.Scaling(1.0f + (Math.Abs(leftWaveForm[audioPosition + 1]) * 0.1f)) * Matrix.Translation(0, 1.0f, 0); worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer); //Shapes.Cube.Begin(context); //Shapes.Cube.Draw(context); Shapes.Sphere.Begin(context); Shapes.Sphere.Draw(context); // Draw Controllers context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; Shaders.NormalTexture.Apply(context); context.PixelShader.SetSampler(0, samplerState); foreach (var controller in controllers) { context.InputAssembler.SetVertexBuffers(0, controllerVertexBufferBindings[controller]); context.InputAssembler.SetIndexBuffer(controllerIndexBuffers[controller], Format.R16_UInt, 0); context.PixelShader.SetShaderResource(0, controllerTextureViews[controller]); Convert(ref currentPoses[controller].mDeviceToAbsoluteTracking, ref world); world = Matrix.Scaling(1.0f + (Math.Abs(leftWaveForm[audioPosition + 1]) * 0.5f)) * world; worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer); context.DrawIndexed((int)controllerModels[controller].unTriangleCount * 3 * 4, 0, 0); } // Draw Waveforms Shaders.Position.Apply(context); world = Matrix.Scaling(100, 2.5f, 1) * Matrix.Translation(0, 1, 1); worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.InputAssembler.PrimitiveTopology = PrimitiveTopology.LineStrip; context.InputAssembler.SetVertexBuffers(0, leftWaveFormVertexBufferBinding); context.Draw(1024, 0); world = Matrix.Scaling(100, 2.5f, 1) * Matrix.Translation(0, 1, -1); worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.InputAssembler.SetVertexBuffers(0, rightWaveFormVertexBufferBinding); context.Draw(1024, 0); // Present Right Eye texture.handle = rightEyeTextureView.Resource.NativePointer; submitError = compositor.Submit(EVREye.Eye_Right, ref texture, ref bounds, EVRSubmitFlags.Submit_Default); if (submitError != EVRCompositorError.None) { System.Diagnostics.Debug.WriteLine(submitError); } // Render Window context.Rasterizer.SetViewport(0, 0, windowSize.Width, windowSize.Height); context.OutputMerger.SetTargets(depthStencilView, backBufferView); context.OutputMerger.SetDepthStencilState(depthStencilState); context.ClearRenderTargetView(backBufferView, backgroundColor); context.ClearDepthStencilView(depthStencilView, DepthStencilClearFlags.Depth, 1.0f, 0); Shaders.Normal.Apply(context); context.Rasterizer.State = rasterizerState; context.OutputMerger.SetBlendState(blendState); context.OutputMerger.SetDepthStencilState(depthStencilState); context.PixelShader.SetSampler(0, samplerState); ratio = (float)form.ClientSize.Width / (float)form.ClientSize.Height; projection = Matrix.PerspectiveFovRH(3.14f / 3.0f, ratio, 0.01f, 1000); view = Matrix.Invert(head); world = Matrix.Scaling(1.0f + (Math.Abs(leftWaveForm[audioPosition + 1]) * 0.1f)) * Matrix.Translation(0, 1.0f, 0); worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer); //Shapes.Cube.Begin(context); //Shapes.Cube.Draw(context); Shapes.Sphere.Begin(context); Shapes.Sphere.Draw(context); // Draw Controllers context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; Shaders.NormalTexture.Apply(context); context.PixelShader.SetSampler(0, samplerState); foreach (var controller in controllers) { context.InputAssembler.SetVertexBuffers(0, controllerVertexBufferBindings[controller]); context.InputAssembler.SetIndexBuffer(controllerIndexBuffers[controller], Format.R16_UInt, 0); Convert(ref currentPoses[controller].mDeviceToAbsoluteTracking, ref world); world = Matrix.Scaling(1.0f + (Math.Abs(leftWaveForm[audioPosition + 1]) * 0.5f)) * world; worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer); context.DrawIndexed((int)controllerModels[controller].unTriangleCount * 3 * 4, 0, 0); } // Draw Waveforms Shaders.Position.Apply(context); world = Matrix.Scaling(100, 2.5f, 1) * Matrix.Translation(0, 1, 1); worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.InputAssembler.PrimitiveTopology = PrimitiveTopology.LineStrip; context.InputAssembler.SetVertexBuffers(0, leftWaveFormVertexBufferBinding); context.Draw(1024, 0); world = Matrix.Scaling(100, 2.5f, 1) * Matrix.Translation(0, 1, -1); worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.InputAssembler.SetVertexBuffers(0, rightWaveFormVertexBufferBinding); context.Draw(1024, 0); // Show Backbuffer swapChain.Present(0, PresentFlags.None); }); } }
public void InitRendering(UI ui) { lock (_drawLock) { if (ui == null) { return; } _ui = ui; ResizeRedraw = true; var initError = EVRInitError.None; system = OpenVR.Init(ref initError); if (initError != EVRInitError.None) { throw new Exception("Not Available"); } compositor = OpenVR.Compositor; compositor.CompositorBringToFront(); compositor.FadeGrid(5.0f, false); count = OpenVR.k_unMaxTrackedDeviceCount; currentPoses = new TrackedDevicePose_t[count]; nextPoses = new TrackedDevicePose_t[count]; controllers = new List <uint>(); controllerModels = new RenderModel_t[count]; controllerTextures = new RenderModel_TextureMap_t[count]; controllerTextureViews = new ShaderResourceView[count]; controllerVertexBuffers = new SharpDX.Direct3D11.Buffer[count]; controllerIndexBuffers = new SharpDX.Direct3D11.Buffer[count]; controllerVertexBufferBindings = new VertexBufferBinding[count]; for (uint device = 0; device < count; device++) { var deviceClass = system.GetTrackedDeviceClass(device); switch (deviceClass) { case ETrackedDeviceClass.HMD: headset = device; break; case ETrackedDeviceClass.Controller: controllers.Add(device); break; } } uint width = 0; uint height = 0; system.GetRecommendedRenderTargetSize(ref width, ref height); headsetSize = new Size((int)width, (int)height); windowSize = new Size(UI.GameWidth, UI.GameHeight); leftEyeProjection = Convert(system.GetProjectionMatrix(EVREye.Eye_Left, 0.01f, 1000.0f)); rightEyeProjection = Convert(system.GetProjectionMatrix(EVREye.Eye_Right, 0.01f, 1000.0f)); leftEyeView = Convert(system.GetEyeToHeadTransform(EVREye.Eye_Left)); rightEyeView = Convert(system.GetEyeToHeadTransform(EVREye.Eye_Right)); foreach (var controller in controllers) { var modelName = new StringBuilder(255, 255); var propertyError = ETrackedPropertyError.TrackedProp_Success; var length = system.GetStringTrackedDeviceProperty(controller, ETrackedDeviceProperty.Prop_RenderModelName_String, modelName, 255, ref propertyError); if (propertyError == ETrackedPropertyError.TrackedProp_Success) { var modelName2 = modelName.ToString(); while (true) { var pointer = IntPtr.Zero; var modelError = EVRRenderModelError.None; modelError = OpenVR.RenderModels.LoadRenderModel_Async(modelName2, ref pointer); if (modelError == EVRRenderModelError.Loading) { continue; } if (modelError == EVRRenderModelError.None) { var renderModel = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_t>(pointer); controllerModels[controller] = renderModel; break; } } while (true) { var pointer = IntPtr.Zero; var textureError = EVRRenderModelError.None; textureError = OpenVR.RenderModels.LoadTexture_Async(controllerModels[controller].diffuseTextureId, ref pointer); if (textureError == EVRRenderModelError.Loading) { continue; } if (textureError == EVRRenderModelError.None) { var texture = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_TextureMap_t>(pointer); controllerTextures[controller] = texture; break; } } } } int adapterIndex = 0; system.GetDXGIOutputInfo(ref adapterIndex); using (var factory = new SharpDX.DXGI.Factory4()) { var adapter = factory.GetAdapter(adapterIndex); var swapChainDescription = new SwapChainDescription { BufferCount = 1, Flags = SwapChainFlags.None, IsWindowed = true, ModeDescription = new ModeDescription { Format = Format.B8G8R8A8_UNorm, Width = windowSize.Width, Height = windowSize.Height, RefreshRate = new Rational(60, 1) }, OutputHandle = this.Handle, SampleDescription = new SampleDescription(1, 0), SwapEffect = SwapEffect.Discard, Usage = Usage.RenderTargetOutput }; SharpDX.Direct3D11.Device.CreateWithSwapChain(adapter, DeviceCreationFlags.None, swapChainDescription, out device, out swapChain); factory.MakeWindowAssociation(this.Handle, WindowAssociationFlags.None); context = device.ImmediateContext; using (var backBuffer = swapChain.GetBackBuffer <Texture2D>(0)) backBufferView = new RenderTargetView(device, backBuffer); var depthBufferDescription = new Texture2DDescription { Format = Format.D16_UNorm, ArraySize = 1, MipLevels = 1, Width = windowSize.Width, Height = windowSize.Height, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default, BindFlags = BindFlags.DepthStencil, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.None }; using (var depthBuffer = new Texture2D(device, depthBufferDescription)) depthStencilView = new DepthStencilView(device, depthBuffer); // Create Eye Textures var eyeTextureDescription = new Texture2DDescription { ArraySize = 1, BindFlags = BindFlags.RenderTarget, CpuAccessFlags = CpuAccessFlags.None, Format = Format.B8G8R8A8_UNorm, Width = headsetSize.Width, Height = headsetSize.Height, MipLevels = 1, OptionFlags = ResourceOptionFlags.None, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default }; leftEyeTexture = new Texture2D(device, eyeTextureDescription); rightEyeTexture = new Texture2D(device, eyeTextureDescription); leftEyeTextureView = new RenderTargetView(device, leftEyeTexture); rightEyeTextureView = new RenderTargetView(device, rightEyeTexture); // Create Eye Depth Buffer eyeTextureDescription.BindFlags = BindFlags.DepthStencil; eyeTextureDescription.Format = Format.D32_Float; eyeDepth = new Texture2D(device, eyeTextureDescription); eyeDepthView = new DepthStencilView(device, eyeDepth); Shapes.Cube.Load(device); Shapes.Sphere.Load(device); Shaders.Normal.Load(device); Shaders.NormalTexture.Load(device); // Load Controller Models foreach (var controller in controllers) { var model = controllerModels[controller]; controllerVertexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rVertexData, new BufferDescription { BindFlags = BindFlags.VertexBuffer, SizeInBytes = (int)model.unVertexCount * 32 }); controllerVertexBufferBindings[controller] = new VertexBufferBinding(controllerVertexBuffers[controller], 32, 0); controllerIndexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rIndexData, new BufferDescription { BindFlags = BindFlags.IndexBuffer, SizeInBytes = (int)model.unTriangleCount * 3 * 2 }); var texture = controllerTextures[controller]; using (var texture2d = new Texture2D(device, new Texture2DDescription { ArraySize = 1, BindFlags = BindFlags.ShaderResource, Format = Format.R8G8B8A8_UNorm, Width = texture.unWidth, Height = texture.unHeight, MipLevels = 1, SampleDescription = new SampleDescription(1, 0) }, new DataRectangle(texture.rubTextureMapData, texture.unWidth * 4))) controllerTextureViews[controller] = new ShaderResourceView(device, texture2d); } shaderParameterBuffer = new SharpDX.Direct3D11.Buffer(device, Utilities.SizeOf <Shaders.Parameters>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0); var rasterizerStateDescription = RasterizerStateDescription.Default(); //rasterizerStateDescription.FillMode = FillMode.Wireframe; rasterizerStateDescription.IsFrontCounterClockwise = true; //rasterizerStateDescription.CullMode = CullMode.None; rasterizerState = new RasterizerState(device, rasterizerStateDescription); var blendStateDescription = BlendStateDescription.Default(); blendStateDescription.RenderTarget[0].BlendOperation = BlendOperation.Add; blendStateDescription.RenderTarget[0].SourceBlend = BlendOption.SourceAlpha; blendStateDescription.RenderTarget[0].DestinationBlend = BlendOption.InverseSourceAlpha; blendStateDescription.RenderTarget[0].IsBlendEnabled = false; blendState = new BlendState(device, blendStateDescription); var depthStateDescription = DepthStencilStateDescription.Default(); depthStateDescription.DepthComparison = Comparison.LessEqual; depthStateDescription.IsDepthEnabled = true; depthStateDescription.IsStencilEnabled = false; depthStencilState = new DepthStencilState(device, depthStateDescription); var samplerStateDescription = SamplerStateDescription.Default(); samplerStateDescription.Filter = Filter.MinMagMipLinear; samplerStateDescription.AddressU = TextureAddressMode.Wrap; samplerStateDescription.AddressV = TextureAddressMode.Wrap; samplerState = new SamplerState(device, samplerStateDescription); startTime = DateTime.Now; frame = 0; //windowSize = ClientSize; backgroundColor = new RawColor4(0.1f, 0.1f, 0.1f, 1); head = Matrix.Identity; _ui.ready = true; } } }
private static void UpdateDevices(CVRSystem system, ref uint overlayIndex) { m_Lock.EnterWriteLock(); try { m_Devices.Clear(); } finally { m_Lock.ExitWriteLock(); } var sb = new StringBuilder(256); var state = new VRControllerState_t(); for (var i = 0u; i < OpenVR.k_unMaxTrackedDeviceCount; ++i) { var devClass = system.GetTrackedDeviceClass(i); if (devClass == ETrackedDeviceClass.Controller || devClass == ETrackedDeviceClass.GenericTracker || devClass == ETrackedDeviceClass.TrackingReference) { var err = ETrackedPropertyError.TrackedProp_Success; var batteryPercentage = system.GetFloatTrackedDeviceProperty(i, ETrackedDeviceProperty.Prop_DeviceBatteryPercentage_Float, ref err); if (err != ETrackedPropertyError.TrackedProp_Success) { batteryPercentage = 1f; } sb.Clear(); system.GetStringTrackedDeviceProperty(i, ETrackedDeviceProperty.Prop_TrackingSystemName_String, sb, (uint)sb.Capacity, ref err); var isOculus = sb.ToString().IndexOf("oculus", StringComparison.OrdinalIgnoreCase) >= 0; // Oculus : B/Y, Bit 1, Mask 2 // Oculus : A/X, Bit 7, Mask 128 // Vive : Menu, Bit 1, Mask 2, // Vive : Grip, Bit 2, Mask 4 var role = system.GetControllerRoleForTrackedDeviceIndex(i); if (role == ETrackedControllerRole.LeftHand || role == ETrackedControllerRole.RightHand) { if (system.GetControllerState(i, ref state, (uint)Marshal.SizeOf(state)) && (state.ulButtonPressed & (isOculus ? 2u : 4u)) != 0) { if (role == ETrackedControllerRole.LeftHand) { Array.Copy(m_L_Translation, m_Translation, 3); Array.Copy(m_L_Rotation, m_Rotation, 3); } else { Array.Copy(m_R_Translation, m_Translation, 3); Array.Copy(m_R_Rotation, m_Rotation, 3); } overlayIndex = i; } } var type = string.Empty; if (devClass == ETrackedDeviceClass.Controller) { if (role == ETrackedControllerRole.LeftHand) { type = "leftController"; } else if (role == ETrackedControllerRole.RightHand) { type = "rightController"; } else { type = "controller"; } } else if (devClass == ETrackedDeviceClass.GenericTracker) { type = "tracker"; } else if (devClass == ETrackedDeviceClass.TrackingReference) { type = "base"; } var item = new[] { type, system.IsTrackedDeviceConnected(i) ? "connected" : "disconnected", (batteryPercentage * 100).ToString() }; m_Lock.EnterWriteLock(); try { m_Devices.Add(item); } finally { m_Lock.ExitWriteLock(); } } } }
public unsafe override bool GatherInput(XRControllerState[] state_controllers, out int controllerCount, out bool leftSet, out int leftSetIndex, out bool rightSet, out int rightSetIndex, out SideToSet sideToSet) { // defaults GatherInputDefaults(out controllerCount, out leftSet, out leftSetIndex, out rightSet, out rightSetIndex, out sideToSet); // reset controllers ResetControllers(state_controllers); // validate OpenVR is avaliable if (!isInit) { return(false); } if (system == null || !system.IsInputAvailable() || input.IsUsingLegacyInput()) { return(false); } // get controller connection status and side for (uint i = 0; i != OpenVR.k_unMaxTrackedDeviceCount; ++i) { if (!system.IsTrackedDeviceConnected(i)) { continue; } if (system.GetTrackedDeviceClass(i) != ETrackedDeviceClass.Controller) { continue; } // get controller type ETrackedPropertyError e = ETrackedPropertyError.TrackedProp_Success; system.GetStringTrackedDeviceProperty(i, ETrackedDeviceProperty.Prop_ControllerType_String, OpenVR_Shared.propertyText, (uint)OpenVR_Shared.propertyText.Capacity, ref e); if (e != ETrackedPropertyError.TrackedProp_Success) { continue; } // ignore gamepads if (OpenVR_Shared.propertyText.Equals(OpenVR_Shared.propertyText_Gamepad)) { continue; } // get controller var controller = state_controllers[controllerCount]; controller.connected = true; // get controller type if (OpenVR_Shared.propertyText.Equals(OpenVR_Shared.propertyText_ViveController)) { controller.type = XRInputControllerType.HTCVive; } else if (OpenVR_Shared.propertyText.Equals(OpenVR_Shared.propertyText_ViveCosmosController)) { controller.type = XRInputControllerType.HTCViveCosmos; } else if (OpenVR_Shared.propertyText.Equals(OpenVR_Shared.propertyText_IndexController)) { controller.type = XRInputControllerType.ValveIndex; } else if (OpenVR_Shared.propertyText.ToString().StartsWith(OpenVR_Shared.propertyText_Oculus.ToString())) { controller.type = XRInputControllerType.Oculus; } else if (OpenVR_Shared.propertyText.Equals(OpenVR_Shared.propertyText_WMR)) { controller.type = XRInputControllerType.WMR; } else if (OpenVR_Shared.propertyText.Equals(OpenVR_Shared.propertyText_WMR_G2)) { controller.type = XRInputControllerType.WMR_G2; } // update controller side var role = system.GetControllerRoleForTrackedDeviceIndex(i); switch (role) { case ETrackedControllerRole.LeftHand: controller.side = XRControllerSide.Left; leftSet = true; leftSetIndex = controllerCount; leftHand = (int)i; break; case ETrackedControllerRole.RightHand: controller.side = XRControllerSide.Right; rightSet = true; rightSetIndex = controllerCount; rightHand = (int)i; break; default: controller.side = XRControllerSide.Unknown; break; } state_controllers[controllerCount] = controller; ++controllerCount; } // pre-finish/pre-resolve unknown controller sides GatherInputFinish(state_controllers, controllerCount, ref leftSet, ref leftSetIndex, ref rightSet, ref rightSetIndex, ref sideToSet); // update inputs var error = input.UpdateActionState(actionSets, (uint)Marshal.SizeOf <VRActiveActionSet_t>()); if (error != EVRInputError.None) { Debug.LogError("UpdateActionState: " + error.ToString()); } // get hands var controllerRight = new XRControllerState(); var controllerLeft = new XRControllerState(); if (rightSet) { controllerRight = state_controllers[rightSetIndex]; } if (leftSet) { controllerLeft = state_controllers[leftSetIndex]; } // update bumper buttons/touch controllerRight.buttonBumper.Update(GetButtonState(viveAction_BumperButton, viveSource_RightHand)); controllerLeft.buttonBumper.Update(GetButtonState(viveAction_BumperButton, viveSource_LeftHand)); controllerRight.touchBumper.Update(GetButtonState(viveAction_BumperTouch, viveSource_RightHand)); controllerLeft.touchBumper.Update(GetButtonState(viveAction_BumperTouch, viveSource_LeftHand)); // update trigger buttons/touch controllerRight.buttonTrigger.Update(GetButtonState(viveAction_TriggerButton, viveSource_RightHand)); controllerLeft.buttonTrigger.Update(GetButtonState(viveAction_TriggerButton, viveSource_LeftHand)); controllerRight.touchTrigger.Update(GetButtonState(viveAction_TriggerTouch, viveSource_RightHand)); controllerLeft.touchTrigger.Update(GetButtonState(viveAction_TriggerTouch, viveSource_LeftHand)); // update grip buttons/touch controllerRight.buttonGrip.Update(GetButtonState(viveAction_GripButton, viveSource_RightHand)); controllerLeft.buttonGrip.Update(GetButtonState(viveAction_GripButton, viveSource_LeftHand)); controllerRight.touchGrip.Update(GetButtonState(viveAction_GripTouch, viveSource_RightHand)); controllerLeft.touchGrip.Update(GetButtonState(viveAction_GripTouch, viveSource_LeftHand)); // update menu buttons/touch controllerRight.buttonMenu.Update(GetButtonState(viveAction_MenuButton, viveSource_RightHand)); controllerLeft.buttonMenu.Update(GetButtonState(viveAction_MenuButton, viveSource_LeftHand)); controllerRight.touchMenu.Update(GetButtonState(viveAction_MenuTouch, viveSource_RightHand)); controllerLeft.touchMenu.Update(GetButtonState(viveAction_MenuTouch, viveSource_LeftHand)); // update button/touch 1 controllerRight.button1.Update(GetButtonState(viveAction_Button1, viveSource_RightHand)); controllerLeft.button1.Update(GetButtonState(viveAction_Button1, viveSource_LeftHand)); controllerRight.touch1.Update(GetButtonState(viveAction_Touch1, viveSource_RightHand)); controllerLeft.touch1.Update(GetButtonState(viveAction_Touch1, viveSource_LeftHand)); // update button/touch 2 controllerRight.button2.Update(GetButtonState(viveAction_Button2, viveSource_RightHand)); controllerLeft.button2.Update(GetButtonState(viveAction_Button2, viveSource_LeftHand)); controllerRight.touch2.Update(GetButtonState(viveAction_Touch2, viveSource_RightHand)); controllerLeft.touch2.Update(GetButtonState(viveAction_Touch2, viveSource_LeftHand)); // update grip if (controllerRight.type == XRInputControllerType.HTCVive || controllerRight.type == XRInputControllerType.WMR) { controllerRight.grip.Update(controllerRight.buttonGrip.on ? 1 : 0);// simulate analog state } else { controllerRight.grip.Update(GetAnalogState(viveAction_Grip, viveSource_RightHand).x); } if (controllerLeft.type == XRInputControllerType.HTCVive || controllerLeft.type == XRInputControllerType.WMR) { controllerLeft.grip.Update(controllerLeft.buttonGrip.on ? 1 : 0);// simulate analog state } else { controllerLeft.grip.Update(GetAnalogState(viveAction_Grip, viveSource_LeftHand).x); } // update triggers controllerRight.trigger.Update(GetAnalogState(viveAction_Trigger, viveSource_RightHand).x); controllerLeft.trigger.Update(GetAnalogState(viveAction_Trigger, viveSource_LeftHand).x); // update trackpads / touch / button if (controllerRight.type == XRInputControllerType.HTCVive) { controllerRight.joystick.Update(GetAnalogState(viveAction_Touchpad1, viveSource_RightHand)); controllerRight.buttonJoystick.Update(GetButtonState(viveAction_Touchpad1_Button, viveSource_RightHand)); } else { controllerRight.joystick2.Update(GetAnalogState(viveAction_Touchpad1, viveSource_RightHand)); controllerRight.buttonJoystick2.Update(GetButtonState(viveAction_Touchpad1_Button, viveSource_RightHand)); } if (controllerLeft.type == XRInputControllerType.HTCVive) { controllerLeft.joystick.Update(GetAnalogState(viveAction_Touchpad1, viveSource_LeftHand)); controllerLeft.buttonJoystick.Update(GetButtonState(viveAction_Touchpad1_Button, viveSource_LeftHand)); } else { controllerLeft.joystick2.Update(GetAnalogState(viveAction_Touchpad1, viveSource_LeftHand)); controllerLeft.buttonJoystick2.Update(GetButtonState(viveAction_Touchpad1_Button, viveSource_LeftHand)); } // update joysticks / touch / button if (controllerRight.type != XRInputControllerType.HTCVive) { controllerRight.joystick.Update(GetAnalogState(viveAction_Joystick1, viveSource_RightHand)); controllerRight.touchJoystick.Update(GetButtonState(viveAction_Joystick1_Touch, viveSource_RightHand)); controllerRight.buttonJoystick.Update(GetButtonState(viveAction_Joystick1_Button, viveSource_RightHand)); } if (controllerLeft.type != XRInputControllerType.HTCVive) { controllerLeft.joystick.Update(GetAnalogState(viveAction_Joystick1, viveSource_LeftHand)); controllerLeft.touchJoystick.Update(GetButtonState(viveAction_Joystick1_Touch, viveSource_LeftHand)); controllerLeft.buttonJoystick.Update(GetButtonState(viveAction_Joystick1_Button, viveSource_LeftHand)); } // copy back hand updates if (rightSet) { state_controllers[rightSetIndex] = controllerRight; } if (leftSet) { state_controllers[leftSetIndex] = controllerLeft; } return(true); }
static void Main() { var initError = EVRInitError.None; system = OpenVR.Init(ref initError); if (initError != EVRInitError.None) { return; } compositor = OpenVR.Compositor; compositor.CompositorBringToFront(); compositor.FadeGrid(5.0f, false); count = OpenVR.k_unMaxTrackedDeviceCount; currentPoses = new TrackedDevicePose_t[count]; nextPoses = new TrackedDevicePose_t[count]; controllers = new List <uint>(); controllerModels = new RenderModel_t[count]; controllerTextures = new RenderModel_TextureMap_t[count]; controllerTextureViews = new ShaderResourceView[count]; controllerVertexBuffers = new SharpDX.Direct3D11.Buffer[count]; controllerIndexBuffers = new SharpDX.Direct3D11.Buffer[count]; controllerVertexBufferBindings = new VertexBufferBinding[count]; 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(); } }