diff --git a/Source/OpenTK/GLControl.cs b/Source/OpenTK/GLControl.cs index d8f9dce4..8f9933de 100644 --- a/Source/OpenTK/GLControl.cs +++ b/Source/OpenTK/GLControl.cs @@ -124,6 +124,7 @@ namespace OpenTK this.Context.Dispose(); this.Context = null; } + this.window_info.Dispose(); this.window_info = null; } @@ -135,6 +136,7 @@ namespace OpenTK { if (DesignMode) e.Graphics.Clear(BackColor); + base.OnPaint(e); } diff --git a/Source/OpenTK/Platform/Windows/WinGLContext.cs b/Source/OpenTK/Platform/Windows/WinGLContext.cs index 05b77511..7889df53 100644 --- a/Source/OpenTK/Platform/Windows/WinGLContext.cs +++ b/Source/OpenTK/Platform/Windows/WinGLContext.cs @@ -147,7 +147,8 @@ namespace OpenTK.Platform.Windows public void SwapBuffers() { if (!Functions.SwapBuffers(currentWindow.DeviceContext)) - Debug.Print("SwapBuffers failed, error: {0}", Marshal.GetLastWin32Error()); + throw new GraphicsContextException(String.Format( + "Failed to swap buffers for context {0} current. Error: {1}", this, Marshal.GetLastWin32Error())); } #endregion @@ -395,11 +396,13 @@ namespace OpenTK.Platform.Windows { if (!disposed) { - DestroyContext(); - if (calledManually) { - // Safe to clean managed resources + DestroyContext(); + } + else + { + Debug.Print("[Warning] OpenGL context {0} leaked. Did you forget to call IGraphicsContext.Dispose()?", renderContext.Handle); } disposed = true; } @@ -421,10 +424,7 @@ namespace OpenTK.Platform.Windows { try { - if (!Wgl.Imports.MakeCurrent(IntPtr.Zero, IntPtr.Zero)) - Debug.Print("Failed to make OpenGL context {0} non current. Error: {1}", - renderContext.ToString(), Marshal.GetLastWin32Error()); - + // This will fail if the user calls Dispose() on thread X when the context is current on thread Y. if (!Wgl.Imports.DeleteContext(renderContext.Handle)) Debug.Print("Failed to destroy OpenGL context {0}. Error: {1}", renderContext.ToString(), Marshal.GetLastWin32Error()); @@ -439,27 +439,6 @@ namespace OpenTK.Platform.Windows } renderContext = ContextHandle.Zero; } - - //if (deviceContext != IntPtr.Zero) - //{ - // if (!Functions.ReleaseDC(this.windowInfo.Handle, deviceContext)) - // { - // //throw new ApplicationException("Could not release device context. Error: " + Marshal.GetLastWin32Error()); - // //Debug.Print("Could not destroy the device context. Error: {0}", Marshal.GetLastWin32Error()); - // } - //} - - /* - if (opengl32Handle != IntPtr.Zero) - { - if (!Functions.FreeLibrary(opengl32Handle)) - { - //throw new ApplicationException("FreeLibray call failed ('opengl32.dll'), Error: " + Marshal.GetLastWin32Error()); - //Debug.Print("Could not release {0}. Error: {1}", opengl32Name, Marshal.GetLastWin32Error()); - } - opengl32Handle = IntPtr.Zero; - } - */ } #endregion diff --git a/Source/OpenTK/Platform/Windows/WinGLControl.cs b/Source/OpenTK/Platform/Windows/WinGLControl.cs index 5f75e446..f72c39c8 100644 --- a/Source/OpenTK/Platform/Windows/WinGLControl.cs +++ b/Source/OpenTK/Platform/Windows/WinGLControl.cs @@ -20,19 +20,37 @@ namespace OpenTK.Platform.Windows MSG msg = new MSG(); GraphicsMode mode; Control control; + WinWindowInfo window_info; internal WinGLControl(GraphicsMode mode, Control control) { this.mode = mode; this.control = control; + this.control.HandleCreated += delegate(object sender, EventArgs e) + { + if (window_info != null) + window_info.Dispose(); + window_info = new WinWindowInfo(this.control.Handle, null); + }; + this.control.HandleDestroyed += delegate(object sender, EventArgs e) + { + if (window_info != null) + { + window_info.Dispose(); + window_info = null; + } + }; } #region --- IGLControl Members --- public GraphicsContext CreateContext(int major, int minor, GraphicsContextFlags flags) { - WinWindowInfo window = new WinWindowInfo(control.Handle, null); - return new GraphicsContext(mode, window, major, minor, flags); + // Make sure the Control exists before creating the context. + if (window_info == null) + window_info = new WinWindowInfo(control.Handle, null); + + return new GraphicsContext(mode, window_info, major, minor, flags); } public bool IsIdle @@ -45,7 +63,7 @@ namespace OpenTK.Platform.Windows get { // This method forces the creation of the control. Beware of this side-effect! - return new WinWindowInfo(control.Handle, null); + return window_info; } }