Пример #1
0
        public WebKitOverlay(Uri uri, int windowWidth, int windowHeight, string overlayKey, string overlayName, OverlayType overlayType, bool autoKeyboard = true)
        {
            if (!SteamVR_WebKit.Initialised)
            {
                SteamVR_WebKit.Init();
            }

            _browserSettings = new BrowserSettings();
            _browserSettings.WindowlessFrameRate = 30;
            _uri          = uri;
            _windowWidth  = windowWidth;
            _windowHeight = windowHeight;
            _overlayKey   = overlayKey;
            _overlayName  = overlayName;
            _autoKeyboard = autoKeyboard;

            if (overlayType == OverlayType.Dashboard)
            {
                CreateDashboardOverlay();
            }
            else if (overlayType == OverlayType.InGame)
            {
                CreateInGameOverlay();
            }
            else
            {
                CreateDashboardOverlay();
                CreateInGameOverlay();
            }

            SteamVR_WebKit.Overlays.Add(this);

            SetupTextures();
        }
Пример #2
0
        public Task LoadPageAsync(ChromiumWebBrowser browser, string address = null)
        {
            //If using .Net 4.6 then use TaskCreationOptions.RunContinuationsAsynchronously
            //and switch to tcs.TrySetResult below - no need for the custom extension method
            var tcs = new TaskCompletionSource <bool>();

            EventHandler <LoadingStateChangedEventArgs> handler = null;

            handler = (sender, args) =>
            {
                //Wait for while page to finish loading not just the first frame
                if (!args.IsLoading)
                {
                    SteamVR_WebKit.Log("Page Loaded for " + _overlayKey);
                    PageReady?.Invoke(browser, new EventArgs());

                    browser.LoadingStateChanged -= handler;
                    //This is required when using a standard TaskCompletionSource
                    //Extension method found in the CefSharp.Internals namespace
                    tcs.TrySetResultAsync(true);
                }
            };

            browser.LoadingStateChanged += handler;

            if (!string.IsNullOrEmpty(address))
            {
                browser.Load(address);
            }
            return(tcs.Task);
        }
Пример #3
0
        void CompileShader(string path)
        {
            if (!File.Exists(path))
            {
                SteamVR_WebKit.Log("[OPENGL] No Shader Found at " + path);
                return;
            }

            int fragShaderId = GL.CreateShader(ShaderType.FragmentShader);

            GL.ShaderSource(fragShaderId, File.ReadAllText(path));
            GL.CompileShader(fragShaderId);

            _glFragmentShaderProgramId = GL.CreateProgram();
            GL.AttachShader(_glFragmentShaderProgramId, fragShaderId);
            GL.LinkProgram(_glFragmentShaderProgramId);

            SteamVR_WebKit.Log("[OPENGL] Shader Result: " + GL.GetProgramInfoLog(_glFragmentShaderProgramId));

            GL.DetachShader(_glFragmentShaderProgramId, fragShaderId);
            GL.DeleteShader(fragShaderId);

            GL.Uniform1(GL.GetUniformLocation(_glFragmentShaderProgramId, "_MainTex"), 0);
            GL.ActiveTexture(TextureUnit.Texture0);
            GL.BindTexture(TextureTarget.Texture2D, _glInputTextureId);
        }
Пример #4
0
        //private void DoScreenshot()
        //{
        //    _browser.ScreenshotAsync().ContinueWith(x =>
        //    {
        //        _isRendering = true;

        //        _browserDidUpdate = true;

        //        lock (_bitmapLock)
        //        {
        //            _bitmap = x.Result;
        //        }

        //        BrowserRenderUpdate?.Invoke(this, new EventArgs());
        //        DoScreenshot();
        //    });
        //}

        private void _browser_BrowserInitialized(object sender, EventArgs e)
        {
            SteamVR_WebKit.Log("Browser Initialised for " + _overlayKey);
            BrowserReady?.Invoke(_browser, new EventArgs());
            // DoScreenshot();
            _isRendering = true;

            _browserDidUpdate = true;
        }
Пример #5
0
            void IRenderProcessMessageHandler.OnFocusedNodeChanged(IWebBrowser browserControl, IBrowser browser, IFrame frame, IDomNode node)
            {
                if (DebugMode)
                {
                    SteamVR_WebKit.Log("Node Focus Change: " + (node != null ? node.ToString() : " none"));
                }

                _parent.FocusedNodeChanged?.Invoke(browserControl, browser, frame, node);
            }
 public static void CefShutdown()
 {
     try
     {
         Cef.Shutdown();
     }
     catch (Exception e)
     {
         SteamVR_WebKit.Log("SteamVR_WebKit Cef.Shutdown failed: " + e.Message);
     }
 }
        public static void Init(CefSettings settings = null)
        {
            Overlays = new List <WebKitOverlay>();

            if (settings == null)
            {
                settings = new CefSettings();
            }

            gw = new GameWindow(300, 30); // Invisible GL Context
            GL.Enable(EnableCap.Texture2D);

            if (Cef.IsInitialized)
            {
                Cef.Shutdown();
            }

            Cef.Initialize(settings, performDependencyCheck: true, browserProcessHandler: null);

            bool tryAgain = true;

            while (tryAgain && !_doStop)
            {
                try
                {
                    InitOpenVR();
                    tryAgain = false;
                } catch (Exception e)
                {
                    Log(e.Message);
                    Log("Trying again in 3 seconds");
                    Thread.Sleep(3000);
                }
            }

            if (_doStop)
            {
                CefShutdown();
                return;
            }

            _system       = OpenVR.System;
            _compositor   = OpenVR.Compositor;
            _overlay      = OpenVR.Overlay;
            _applications = OpenVR.Applications;

            _controllerManager = new SteamVR_ControllerManager();

            SteamVR_WebKit.Log("SteamVR_WebKit Initialised");

            _initialised = true;
        }
Пример #8
0
        void CreateOverlayInSteamVR()
        {
            EVROverlayError ovrErr = EVROverlayError.None;

            if (SteamVR_WebKit.OverlayManager == null)
            {
                SteamVR_WebKit.Init();
            }

            if (_ingame)
            {
                ovrErr = SteamVR_WebKit.OverlayManager.CreateOverlay(Key, Name, ref _handle);
                SteamVR_WebKit.OverlayManager.SetOverlayInputMethod(_handle, VROverlayInputMethod.None);
            }
            else
            {
                ovrErr = SteamVR_WebKit.OverlayManager.CreateDashboardOverlay(Key, Name, ref _handle, ref _thumbnailHandle);
                SteamVR_WebKit.OverlayManager.SetOverlayInputMethod(_handle, VROverlayInputMethod.Mouse);
                SteamVR_WebKit.OverlayManager.SetOverlayFlag(_handle, VROverlayFlags.ShowTouchPadScrollWheel, true);
                SteamVR_WebKit.OverlayManager.SetOverlayFlag(_handle, VROverlayFlags.SendVRScrollEvents, true);
            }

            Console.WriteLine("Overlay Handle " + _handle + ", Thumbnail Handle: " + _thumbnailHandle);

            if (ovrErr != EVROverlayError.None)
            {
                throw new Exception("Failed to create overlay: " + ovrErr.ToString());
            }

            SteamVR_WebKit.OverlayManager.SetOverlayAlpha(_handle, 1.0f);
            SteamVR_WebKit.OverlayManager.SetOverlayColor(_handle, 1.0f, 1.0f, 1.0f);


            // Because it'll be upside down otherwise.
            VRTextureBounds_t bounds;

            bounds.vMax = 0; bounds.vMin = 1;  // Flip the Y

            // Leave as defaults
            bounds.uMin = 0;
            bounds.uMax = 1;

            SteamVR_WebKit.OverlayManager.SetOverlayTextureBounds(_handle, ref bounds);
        }
Пример #9
0
        public void KeyboardInput(byte[] characters)
        {
            int len = 0;

            for (int i = 0; i < 8; i++)
            {
                if (characters[i] == 0)
                {
                    continue;
                }

                KeyEvent ev = KeyboardUtils.ConvertCharToVirtualKeyEvent(characters[i]);
                ev.FocusOnEditableField = false;

                SteamVR_WebKit.Log("[KEY] Key Code: " + ev.WindowsKeyCode + " | Modifiers: " + ev.Modifiers.ToString());

                Browser.GetBrowser().GetHost().SendKeyEvent(ev);
            }
        }
Пример #10
0
        public void SetTexture(ref Texture_t texture)
        {
            EVROverlayError err = SteamVR_WebKit.OverlayManager.SetOverlayTexture(_handle, ref texture);

            if (err != EVROverlayError.None)
            {
                SteamVR_WebKit.Log("Failed to send texture: " + err.ToString());
            }

            if (_hasBackSide)
            {
                err = SteamVR_WebKit.OverlayManager.SetOverlayTexture(_backSideHandle, ref texture);

                if (err != EVROverlayError.None)
                {
                    SteamVR_WebKit.Log("Failed to send texture: " + err.ToString());
                }
            }
        }
Пример #11
0
        public void SetDeviceAttachment(uint index, Vector3 position, Vector3 rotation)
        {
            if (!_ingame)
            {
                throw new Exception("Cannot set attachment for dashboard overlay");
            }

            _position = position;
            _rotation = rotation;

            HmdMatrix34_t matrix = GetMatrixFromPositionAndRotation(position, rotation);

            EVROverlayError err = SteamVR_WebKit.OverlayManager.SetOverlayTransformTrackedDeviceRelative(_handle, index, ref matrix);

            if (err != EVROverlayError.None)
            {
                SteamVR_WebKit.Log("Failed to attach " + Key + " to Device " + index + " failed: " + err.ToString());
            }
        }
Пример #12
0
        protected virtual async void AsyncBrowser()
        {
            RequestContextSettings contextSettings = new RequestContextSettings()
            {
                CachePath = CachePath,
            };

            using (RequestContext context = new RequestContext(contextSettings, RequestContextHandler))
            {
                foreach (CefCustomScheme scheme in SchemeHandlers)
                {
                    context.RegisterSchemeHandlerFactory(scheme.SchemeName, scheme.DomainName, scheme.SchemeHandlerFactory);
                }

                SteamVR_WebKit.Log("Browser Initialising for " + _overlayKey);

                _browser = new ChromiumWebBrowser(Uri.ToString(), _browserSettings, context, false);
                Browser.RenderProcessMessageHandler = MessageHandler;
                BrowserPreInit?.Invoke(_browser, new EventArgs());
                _browser.Size = new Size((int)_windowWidth, (int)_windowHeight);
                //_browser.NewScreenshot += Browser_NewScreenshot;

                _browser.BrowserInitialized += _browser_BrowserInitialized;

                _browser.CreateBrowser();

                if (_zoomLevel > 1)
                {
                    _browser.FrameLoadStart += (s, argsi) =>
                    {
                        if (argsi.Frame.IsMain)
                        {
                            ((ChromiumWebBrowser)s).SetZoomLevel(_zoomLevel);
                        }
                    };
                }

                await LoadPageAsync(_browser);
            }

            //If while we waited any JS commands were queued, then run those now
            ExecQueuedJS();
        }
Пример #13
0
        void HandleMouseButtonDownEvent(VREvent_t ev)
        {
            if (ev.data.mouse.button != (uint)EVRMouseButton.Left)
            {
                return;
            }

            _browser.GetBrowser().GetHost().SendMouseClickEvent((int)ev.data.mouse.x, _windowHeight - (int)ev.data.mouse.y, GetMouseButtonType(ev.data.mouse.button), false, 1, CefEventFlags.None);

            if ((EVRMouseButton)ev.data.mouse.button == EVRMouseButton.Left)
            {
                _isHolding = true;
                brokeFromJitterThreshold = false;
                mouseClickPosition       = new OpenTK.Vector2(ev.data.mouse.x, ev.data.mouse.y);

                if (SteamVR_WebKit.TraceLevel)
                {
                    SteamVR_WebKit.Log("[WEBKIT] Mouse Down Event Fired at " + ev.data.mouse.x + "," + ev.data.mouse.y);
                }
            }
        }
Пример #14
0
        public WebKitOverlay(Uri uri, int windowWidth, int windowHeight, string overlayKey, string overlayName, OverlayType overlayType)
        {
            if (!SteamVR_WebKit.Initialised)
            {
                SteamVR_WebKit.Init();
            }

            MessageHandler = new OverlayMessageHandler(this);

            _browserSettings = new BrowserSettings();
            _browserSettings.WindowlessFrameRate = 30;
            _uri          = uri;
            _windowWidth  = windowWidth;
            _windowHeight = windowHeight;
            _overlayKey   = overlayKey;
            _overlayName  = overlayName;

            AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;

            if (overlayType == OverlayType.Dashboard)
            {
                CreateDashboardOverlay();
            }
            else if (overlayType == OverlayType.InGame)
            {
                CreateInGameOverlay();
            }
            else
            {
                CreateDashboardOverlay(true);
                CreateInGameOverlay(true);
            }

            SteamVR_WebKit.Overlays.Add(this);

            FocusedNodeChanged += WebKitOverlay_FocusedNodeChanged;

            SetupTextures();
        }
        private static void OnKeyboardCharInput(params object[] args)
        {
            SteamVR_WebKit.Log("Keyboard Input: " + ((char)((VREvent_t)args[0]).data.keyboard.cNewInput0));

            byte[] characters = new byte[8] {
                ((VREvent_t)args[0]).data.keyboard.cNewInput0,
                ((VREvent_t)args[0]).data.keyboard.cNewInput1,
                ((VREvent_t)args[0]).data.keyboard.cNewInput2,
                ((VREvent_t)args[0]).data.keyboard.cNewInput3,
                ((VREvent_t)args[0]).data.keyboard.cNewInput4,
                ((VREvent_t)args[0]).data.keyboard.cNewInput5,
                ((VREvent_t)args[0]).data.keyboard.cNewInput6,
                ((VREvent_t)args[0]).data.keyboard.cNewInput7,
            };

            if (SteamVR_WebKit.ActiveKeyboardOverlay != null)
            {
                SteamVR_WebKit.ActiveKeyboardOverlay.KeyboardInput(characters);
            }

            // TODO: Take input and send to overlay
        }
Пример #16
0
        void HandleMouseButtonUpEvent(VREvent_t ev)
        {
            if (ev.data.mouse.button != (uint)EVRMouseButton.Left)
            {
                return;
            }

            int xToSend = (int)ev.data.mouse.x;
            int yToSend = (int)ev.data.mouse.y;

            if (_isHolding && !brokeFromJitterThreshold)
            {
                if ((mouseClickPosition - new OpenTK.Vector2(ev.data.mouse.x, ev.data.mouse.y)).Length >= MouseDeltaTolerance)
                {
                    brokeFromJitterThreshold = true;
                }
                else
                {
                    xToSend = (int)mouseClickPosition.X;
                    yToSend = (int)mouseClickPosition.Y;
                }
            }

            _browser.GetBrowser().GetHost().SendMouseClickEvent((int)xToSend, _windowHeight - (int)yToSend, GetMouseButtonType(ev.data.mouse.button), true, 1, CefEventFlags.None);

            if ((EVRMouseButton)ev.data.mouse.button == EVRMouseButton.Left)
            {
                _isHolding = false;
                brokeFromJitterThreshold = false;

                if (SteamVR_WebKit.TraceLevel)
                {
                    SteamVR_WebKit.Log("[WEBKIT] Mouse Up Event Fired at " + xToSend + "," + yToSend);
                }
            }
        }
Пример #17
0
 private void _browser_BrowserInitialized(object sender, EventArgs e)
 {
     SteamVR_WebKit.Log("Browser Initialised for " + _overlayKey);
     BrowserReady?.Invoke(_browser, new EventArgs());
 }
Пример #18
0
        void CreateOverlayInSteamVR()
        {
            EVROverlayError ovrErr = EVROverlayError.None;

            if (SteamVR_WebKit.OverlayManager == null)
            {
                SteamVR_WebKit.Init();
            }

            if (_ingame)
            {
                ovrErr = SteamVR_WebKit.OverlayManager.CreateOverlay(Key, Name, ref _handle);
                ToggleInput(false);
            }
            else
            {
                ovrErr = SteamVR_WebKit.OverlayManager.CreateDashboardOverlay(Key, Name, ref _handle, ref _thumbnailHandle);
                ToggleInput(true);
            }

            SteamVR_WebKit.Log("Overlay Handle " + _handle + ", Thumbnail Handle: " + _thumbnailHandle);

            if (ovrErr != EVROverlayError.None)
            {
                throw new Exception("Failed to create overlay: " + ovrErr.ToString());
            }

            SteamVR_WebKit.OverlayManager.SetOverlayColor(_handle, 1.0f, 1.0f, 1.0f);

            if (_hasBackSide)
            {
                ovrErr = SteamVR_WebKit.OverlayManager.CreateOverlay(Key + "_backside", Name, ref _backSideHandle);

                if (ovrErr != EVROverlayError.None)
                {
                    throw new Exception("Failed to create backside of overlay: " + ovrErr.ToString());
                }
                SteamVR_WebKit.OverlayManager.SetOverlayColor(_backSideHandle, 1.0f, 1.0f, 1.0f);

                HmdMatrix34_t matrix = GetMatrixFromPositionAndRotation(new Vector3(0, 0, 0), new Vector3(0, 180, 0));
                SteamVR_WebKit.OverlayManager.SetOverlayTransformOverlayRelative(_backSideHandle, _handle, ref matrix);
            }

            Alpha = 1.0f;


            // Because it'll be upside down otherwise.
            VRTextureBounds_t bounds;

            bounds.vMax = 0; bounds.vMin = 1;  // Flip the Y

            // Leave as defaults
            bounds.uMin = 0;
            bounds.uMax = 1;

            SteamVR_WebKit.OverlayManager.SetOverlayTextureBounds(_handle, ref bounds);

            if (_hasBackSide)
            {
                bounds.uMin = 1; bounds.uMax = 0; // Flip the backside texture
                SteamVR_WebKit.OverlayManager.SetOverlayTextureBounds(_backSideHandle, ref bounds);
            }
        }
Пример #19
0
        public void SetAttachment(AttachmentType attachmentType, Vector3 position, Vector3 rotation, string attachmentKey = null)
        {
            if (!_ingame)
            {
                throw new Exception("Cannot set attachment for dashboard overlay");
            }

            _attachmentType = attachmentType;

            _position = position;
            _rotation = rotation;

            if (attachmentType == AttachmentType.Absolute)
            {
                HmdMatrix34_t matrix = GetMatrixFromPositionAndRotation(position, rotation);
                SteamVR_WebKit.OverlayManager.SetOverlayTransformAbsolute(_handle, ETrackingUniverseOrigin.TrackingUniverseStanding, ref matrix);
                _sentAttachmentSuccess = true;
            }
            else if (attachmentType == AttachmentType.Hmd)
            {
                SetDeviceAttachment((uint)0, position, rotation);
                _sentAttachmentSuccess = true;
            }
            else if (attachmentType == AttachmentType.Overlay)
            {
                ulong attachmentHandle = 0;

                if (attachmentType == AttachmentType.Overlay && attachmentKey == null)
                {
                    attachmentKey = _attachedTo;
                }

                if (_attachedTo != attachmentKey)
                {
                    SteamVR_WebKit.OverlayManager.FindOverlay(attachmentKey, ref attachmentHandle);
                    _attachedToHandle = attachmentHandle;
                }

                if (_attachedToHandle != 0)
                {
                    HmdMatrix34_t   matrix = GetMatrixFromPositionAndRotation(position, rotation);
                    EVROverlayError err    = SteamVR_WebKit.OverlayManager.SetOverlayTransformOverlayRelative(_handle, _attachedToHandle, ref matrix);

                    if (err != EVROverlayError.None)
                    {
                        SteamVR_WebKit.Log("Failed to attach " + Key + " to Overlay " + attachmentKey + " failed: " + err.ToString());
                    }

                    _sentAttachmentSuccess = true;
                }
                else
                {
                    SteamVR_WebKit.Log("Attempted to attach to " + attachmentKey + " but it could not be found.");
                }
            }
            else if (attachmentType == AttachmentType.AbsoluteRelative)
            {
                ulong attachmentHandle = 0;

                if (attachmentType == AttachmentType.Overlay && attachmentKey == null)
                {
                    attachmentKey = _attachedTo;
                }

                if (_attachedTo != attachmentKey)
                {
                    SteamVR_WebKit.OverlayManager.FindOverlay(attachmentKey, ref attachmentHandle);
                    _attachedToHandle = attachmentHandle;
                }

                if (_attachedToHandle != 0)
                {
                    HmdMatrix34_t matrix = GetMatrixFromPositionAndRotation(position, rotation);
                    HmdMatrix34_t parentMatrix = new HmdMatrix34_t();
                    uint          parentWidth = 0, parentHeight = 0;
                    SteamVR_WebKit.OverlayManager.GetOverlayTextureSize(_attachedToHandle, ref parentWidth, ref parentHeight);
                    EVROverlayError err = SteamVR_WebKit.OverlayManager.GetTransformForOverlayCoordinates(_attachedToHandle, ETrackingUniverseOrigin.TrackingUniverseStanding, new HmdVector2_t()
                    {
                        v0 = parentWidth / 2, v1 = parentHeight / 2
                    }, ref parentMatrix);

                    if (err != EVROverlayError.None)
                    {
                        SteamVR_WebKit.Log("Failed to retrieve overlay position for " + _attachedTo);
                        return;
                    }

                    HmdMatrix34_t resultMatrix = TransformUtils.OpenTKMatrixToOpenVRMatrix(TransformUtils.OpenVRMatrixToOpenTKMatrix(parentMatrix) * TransformUtils.OpenVRMatrixToOpenTKMatrix(matrix));


                    err = SteamVR_WebKit.OverlayManager.SetOverlayTransformAbsolute(_handle, ETrackingUniverseOrigin.TrackingUniverseStanding, ref resultMatrix);

                    if (err != EVROverlayError.None)
                    {
                        SteamVR_WebKit.Log("Failed to attach " + Key + " to Overlay " + attachmentKey + " failed: " + err.ToString());
                    }

                    _sentAttachmentSuccess = true;
                }
                else
                {
                    SteamVR_WebKit.Log("Attempted to attach to " + attachmentKey + " but it could not be found.");
                }
            }
            else
            {
                SetDeviceAttachment(SteamVR_WebKit.OVRSystem.GetTrackedDeviceIndexForControllerRole(attachmentType == AttachmentType.LeftController ? ETrackedControllerRole.LeftHand : ETrackedControllerRole.RightHand), position, rotation);
                if (!_controllerListenersSetup)
                {
                    SteamVR_Event.Listen("TrackedDeviceRoleChanged", HandleDeviceRoleChanged);
                    SteamVR_Event.Listen("device_connected", HandleDeviceConnected);
                    _controllerListenersSetup = true;
                }
                else
                {
                    _sentAttachmentSuccess = true;
                }
            }
        }
 private static void OnKeyboardDone(params object[] args)
 {
     SteamVR_WebKit.Log("Keyboard Done");
 }
 private static void OnKeyboardClosed(params object[] args)
 {
     SteamVR_WebKit.Log("Keyboard Closed");
 }
Пример #22
0
        //private void Browser_NewScreenshot(object sender, EventArgs e)
        //{
        //    ChromiumWebBrowser browser = (ChromiumWebBrowser)sender;

        //    if (browser.Bitmap != null)
        //        _isRendering = true;

        //    _browserDidUpdate = true;

        //    BrowserRenderUpdate?.Invoke(sender, e);
        //}

        protected virtual void SetupTextures()
        {
            SteamVR_WebKit.Log("Setting up texture for " + _overlayKey);
            GL.BindTexture(TextureTarget.Texture2D, 0);

            if (SteamVR_WebKit.TraceLevel)
            {
                SteamVR_WebKit.Log("BindTexture: " + GL.GetError());
            }

            _glInputTextureId = GL.GenTexture();

            if (SteamVR_WebKit.TraceLevel)
            {
                SteamVR_WebKit.Log("GenTexture: " + GL.GetError());
            }

            GL.BindTexture(TextureTarget.Texture2D, _glInputTextureId);

            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);

            if (SteamVR_WebKit.TraceLevel)
            {
                SteamVR_WebKit.Log("TexParameter: " + GL.GetError());
            }

            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);

            if (SteamVR_WebKit.TraceLevel)
            {
                SteamVR_WebKit.Log("TexParameter: " + GL.GetError());
            }

            _textureData             = new Texture_t();
            _textureData.eColorSpace = EColorSpace.Linear;
            _textureData.eType       = ETextureType.OpenGL;
            _textureData.handle      = (IntPtr)_glInputTextureId;

            if (SteamVR_WebKit.UseExperimentalOGL)
            {
                GL.MatrixMode(MatrixMode.Projection);
                GL.LoadIdentity();
                _glFrameBufferId    = GL.GenFramebuffer();
                _glOutputTextureId  = GL.GenTexture();
                _textureData.handle = (IntPtr)_glOutputTextureId;

                GL.BindTexture(TextureTarget.Texture2D, _glOutputTextureId);
                GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, _windowWidth, _windowHeight, 0, OpenTK.Graphics.OpenGL.PixelFormat.Rgba, PixelType.UnsignedByte, IntPtr.Zero);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
                GL.BindTexture(TextureTarget.Texture2D, 0);

                GL.BindFramebuffer(FramebufferTarget.Framebuffer, _glFrameBufferId);

                GL.FramebufferTexture(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, _glOutputTextureId, 0);
                GL.DrawBuffer(DrawBufferMode.ColorAttachment0);

                if (GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer) != FramebufferErrorCode.FramebufferComplete)
                {
                    SteamVR_WebKit.Log("[OPENGL] Failed to setup frame buffer: " + GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer).ToString());
                }

                GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);

                if (SteamVR_WebKit.DefaultFragmentShaderPath != null || FragmentShaderPath != null)
                {
                    SteamVR_WebKit.Log("[OPENGL] Using Fragment Shader");

                    string path = FragmentShaderPath != null ? FragmentShaderPath : SteamVR_WebKit.DefaultFragmentShaderPath;

                    CompileShader(path);
                }
            }

            SteamVR_WebKit.Log("Texture Setup complete for " + _overlayKey);
        }