Esempio n. 1
0
        /// <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());
        }
Esempio n. 2
0
    // 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));
        }
    }
Esempio n. 3
0
        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);
        }
Esempio n. 4
0
        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>");
        }
Esempio n. 5
0
        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>");
        }
Esempio n. 6
0
        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);
        }
Esempio n. 7
0
    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());
    }
Esempio n. 8
0
        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());
        }
Esempio n. 9
0
        /// <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());
        }
Esempio n. 11
0
        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;
        }
Esempio n. 12
0
        //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);
        }
Esempio n. 13
0
        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");
        }
Esempio n. 14
0
        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());
        }
Esempio n. 16
0
        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);
        }
Esempio n. 17
0
        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("");
        }
Esempio n. 18
0
        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("");
            }
        }
Esempio n. 19
0
    //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());
    }
Esempio n. 20
0
        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);
        }
Esempio n. 22
0
        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();
        }
Esempio n. 23
0
        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);
                    });
                }
        }
Esempio n. 24
0
        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;
                }
            }
        }
Esempio n. 25
0
        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();
                    }
                }
            }
        }
Esempio n. 26
0
        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);
        }
Esempio n. 27
0
        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();
                }
        }