public override void MakeCurrent(IWindowInfo window) { lock (LoadLock) { bool success; WinWindowInfo wnd = window as WinWindowInfo; if (wnd != null) { if (wnd.Handle == IntPtr.Zero) { throw new ArgumentException("window", "Must point to a valid window."); } success = TryMakeCurrent(wnd, Handle.Handle); DeviceContext = wnd.DeviceContext; } else { success = Wgl.MakeCurrent(IntPtr.Zero, IntPtr.Zero); DeviceContext = IntPtr.Zero; } if (!success) { throw new GraphicsContextException(String.Format( "Failed to make context {0} current. Error: {1}", this, Marshal.GetLastWin32Error())); } } }
public void Dispose() { if (Context != ContextHandle.Zero) { Wgl.MakeCurrent(IntPtr.Zero, IntPtr.Zero); Wgl.DeleteContext(Context.Handle); } }
public TemporaryContext(INativeWindow native) { Debug.WriteLine("[WGL] Creating temporary context to load extensions"); if (native == null) { throw new ArgumentNullException(); } // Create temporary context and load WGL entry points // First, set a compatible pixel format to the device context // of the temp window WinWindowInfo window = native.WindowInfo as WinWindowInfo; WinGraphicsMode selector = new WinGraphicsMode(window.DeviceContext); WinGLContext.SetGraphicsModePFD(selector, GraphicsMode.Default, window); bool success = false; // Then, construct a temporary context and load all wgl extensions Context = new ContextHandle(Wgl.CreateContext(window.DeviceContext)); if (Context != ContextHandle.Zero) { // Make the context current. // Note: on some video cards and on some virtual machines, wglMakeCurrent // may fail with an errorcode of 6 (INVALID_HANDLE). The suggested workaround // is to call wglMakeCurrent in a loop until it succeeds. // See https://www.opengl.org/discussion_boards/showthread.php/171058-nVidia-wglMakeCurrent()-multiple-threads // Sigh... for (int retry = 0; retry < 5 && !success; retry++) { success = Wgl.MakeCurrent(window.DeviceContext, Context.Handle); if (!success) { Debug.Print("wglMakeCurrent failed with error: {0}. Retrying", Marshal.GetLastWin32Error()); System.Threading.Thread.Sleep(10); } } } else { Debug.Print("[WGL] CreateContext failed with error: {0}", Marshal.GetLastWin32Error()); } if (!success) { Debug.WriteLine("[WGL] Failed to create temporary context"); } }
/// <summary> /// Tries to make the context current over several attempts. /// </summary> /// <remarks> /// On some video cards and on some virtual machines, wglMakeCurrent /// may fail with an error code of 6 (INVALID_HANDLE). The suggested workaround /// is to call wglMakeCurrent in a loop until it succeeds. /// See https://www.opengl.org/discussion_boards/showthread.php/171058-nVidia-wglMakeCurrent()-multiple-threads /// In a majority of cases this will succeed on the first try. /// </remarks> /// <returns>Whether the context was successfully made current.</returns> private static bool TryMakeCurrent(WinWindowInfo window, IntPtr contextHandle) { bool success = false; for (int retry = 0; retry < 10 && !success; retry++) { success = Wgl.MakeCurrent(window.DeviceContext, contextHandle); if (!success) { Debug.Print("wglMakeCurrent failed with error: {0}. Retrying", Marshal.GetLastWin32Error()); System.Threading.Thread.Sleep(10); } } return(success); }