diff --git a/Source/OpenTK/GLContext.cs b/Source/OpenTK/GLContext.cs
index 8332b73b..ad2c4d8d 100644
--- a/Source/OpenTK/GLContext.cs
+++ b/Source/OpenTK/GLContext.cs
@@ -15,16 +15,18 @@ namespace OpenTK
///
/// Represents and provides methods to manipulate an OpenGL render context.
///
- public class GLContext : IGLContext
+ public sealed class GLContext : IGLContext, IGLContextInternal, IGLContextCreationHack
{
IGLContext implementation; // The actual render context implementation for the underlying platform.
List dispose_queue = new List();
-
- static SortedList available_contexts =
- new SortedList(); // Contains all available OpenGL contexts.
- delegate IntPtr GetCurrentContextDelegate();
- static GetCurrentContextDelegate StaticGetCurrentContext;
+ bool disposed;
+
+ static Dictionary available_contexts =
+ new Dictionary(); // Contains all available OpenGL contexts.
+
+ //delegate IntPtr GetCurrentContextDelegate();
+ //static GetCurrentContextDelegate StaticGetCurrentContext;
#region public GLContext(DisplayMode mode, IWindowInfo window)
@@ -35,65 +37,73 @@ namespace OpenTK
///
public GLContext(DisplayMode mode, IWindowInfo window)
{
- if (available_contexts.Count == 0)
- available_contexts.Add(0, new WeakReference(null));
+ //if (available_contexts.Count == 0)
+ // available_contexts.Add(IntPtr.Zero, new WeakReference(null));
switch (Environment.OSVersion.Platform)
{
case PlatformID.Unix:
case (PlatformID)128:
- implementation = new OpenTK.Platform.X11.X11GLContext(mode, window);
+ implementation = new OpenTK.Platform.X11.X11GLContext();
break;
case PlatformID.Win32NT:
case PlatformID.Win32S:
case PlatformID.Win32Windows:
case PlatformID.WinCE:
- implementation = new OpenTK.Platform.Windows.WinGLContext(mode, window);
+ implementation = new OpenTK.Platform.Windows.WinGLContext();
break;
default:
- throw new PlatformNotSupportedException("Your platform is not supported currently. Please, refer to http://opentk.sourceforge.net for more information.");
+ throw new PlatformNotSupportedException("Your platform is not supported currently. Please, refer to http://www.opentk.com for more information.");
}
}
#endregion
- #region public static IGLContext CurrentContext
+ #region void ContextDestroyed(IGLContext context, EventArgs e)
- public static GLContext CurrentContext
+ ///
+ /// Handles the Destroy event.
+ ///
+ /// The OpenTK.Platform.IGLContext that was destroyed.
+ /// Not used.
+ void ContextDestroyed(IGLContext context, EventArgs e)
{
- get { return (GLContext)available_contexts[StaticGetCurrentContext().ToInt64()].Target; }
+ this.Destroy -= ContextDestroyed;
+ available_contexts.Remove(((IGLContextInternal)this).Context);
}
#endregion
+ #region --- Public Members ---
+
+ #region public static IGLContext CurrentContext
+
+ internal delegate ContextHandle GetCurrentContextDelegate();
+ internal static GetCurrentContextDelegate GetCurrentContext;
+
+ ///
+ /// Returns the context which is current in the calling thread.
+ ///
+ public static GLContext CurrentContext
+ {
+ get
+ {
+ if (available_contexts.Count > 0)
+ return (GLContext)available_contexts[GetCurrentContext()].Target;
+ //return (GLContext)available_contexts[((IGLContextInternal)available_contexts[IntPtr.Zero].Target).GetCurrentContext()].Target;
+ return null;
+ //return (GLContext)available_contexts[StaticGetCurrentContext().ToInt64()].Target;
+ }
+ }
+
+ #endregion
+
+ #endregion
+
#region --- IGLContext Members ---
- ///
- /// Gets a handle to the OpenGL rendering context.
- ///
- public IntPtr Context
- {
- get { return implementation.Context; }
- }
-
- ///
- /// Gets the IWindowInfo describing the window associated with this context.
- ///
- public IWindowInfo Info
- {
- get { return implementation.Info; }
- }
-
- ///
- /// Gets the DisplayMode of the context.
- ///
- public DisplayMode Mode
- {
- get { return implementation.Mode; }
- }
-
///
/// Creates an OpenGL context.
///
@@ -132,10 +142,11 @@ namespace OpenTK
public void CreateContext(bool direct, IGLContext source)
{
implementation.CreateContext(direct, source);
+ this.Destroy += ContextDestroyed;
- available_contexts.Add(Context.ToInt64(), new WeakReference(this));
- if (StaticGetCurrentContext == null)
- StaticGetCurrentContext = implementation.GetCurrentContext;
+ available_contexts.Add((this as IGLContextInternal).Context, new WeakReference(this));
+ //if (StaticGetCurrentContext == null)
+ // StaticGetCurrentContext = implementation.GetCurrentContext;
}
///
@@ -162,16 +173,6 @@ namespace OpenTK
get { return implementation.IsCurrent; }
}
- ///
- /// Gets a System.IntPtr containing the handle to the OpenGL context which is current in the
- /// calling thread, or IntPtr.Zero if no OpenGL context is current.
- ///
- /// A System.IntPtr that holds the handle to the current OpenGL context.
- public IntPtr GetCurrentContext()
- {
- return implementation.GetCurrentContext();
- }
-
///
/// Raised when a Context is destroyed.
///
@@ -181,29 +182,6 @@ namespace OpenTK
remove { implementation.Destroy -= value; }
}
- ///
- /// Gets the address of an OpenGL extension function.
- ///
- /// The name of the OpenGL function (e.g. "glGetString")
- ///
- /// A pointer to the specified function or IntPtr.Zero if the function isn't
- /// available in the current opengl context.
- ///
- ///
- public IntPtr GetAddress(string function)
- {
- return implementation.GetAddress(function);
- }
-
- ///
- /// Returns the display modes supported by the current opengl context.
- ///
- /// An IEnumerable containing all supported display modes.
- public IEnumerable GetDisplayModes()
- {
- return implementation.GetDisplayModes();
- }
-
///
/// Gets or sets a value indicating whether VSync is enabled.
///
@@ -213,11 +191,50 @@ namespace OpenTK
set { implementation.VSync = value; }
}
+ #endregion
+
+ #region --- IGLContextInternal Members ---
+
+ ///
+ /// Gets a handle to the OpenGL rendering context.
+ ///
+ ContextHandle IGLContextInternal.Context
+ {
+ get { return ((IGLContextInternal)implementation).Context; }
+ }
+
+ ///
+ /// Gets the IWindowInfo describing the window associated with this context.
+ ///
+ IWindowInfo IGLContextInternal.Info
+ {
+ get { return (implementation as IGLContextInternal).Info; }
+ //internal set { (implementation as IGLContextInternal).Info = value; }
+ }
+
+ ///
+ /// Gets the DisplayMode of the context.
+ ///
+ DisplayMode IGLContextInternal.Mode
+ {
+ get { return (implementation as IGLContextInternal).Mode; }
+ }
+
+ ///
+ /// Gets a System.IntPtr containing the handle to the OpenGL context which is current in the
+ /// calling thread, or IntPtr.Zero if no OpenGL context is current.
+ ///
+ /// A System.IntPtr that holds the handle to the current OpenGL context.
+ ContextHandle IGLContextInternal.GetCurrentContext()
+ {
+ return (implementation as IGLContextInternal).GetCurrentContext();
+ }
+
///
/// Registers an OpenGL resource for disposal.
///
/// The OpenGL resource to dispose.
- public void RegisterForDisposal(IDisposable resource)
+ void IGLContextInternal.RegisterForDisposal(IDisposable resource)
{
GC.KeepAlive(resource);
dispose_queue.Add(resource);
@@ -226,28 +243,141 @@ namespace OpenTK
///
/// Disposes all registered OpenGL resources.
///
- public void DisposeResources()
+ void IGLContextInternal.DisposeResources()
{
foreach (IDisposable resource in dispose_queue)
- {
resource.Dispose();
- }
+
dispose_queue.Clear();
}
+ ///
+ /// Returns the display modes supported by the current opengl context.
+ ///
+ /// An IEnumerable containing all supported display modes.
+ IEnumerable IGLContextInternal.GetDisplayModes()
+ {
+ return (implementation as IGLContextInternal).GetDisplayModes();
+ }
+
+ ///
+ /// Gets the address of an OpenGL extension function.
+ ///
+ /// The name of the OpenGL function (e.g. "glGetString")
+ ///
+ /// A pointer to the specified function or IntPtr.Zero if the function isn't
+ /// available in the current opengl context.
+ ///
+ ///
+ IntPtr IGLContextInternal.GetAddress(string function)
+ {
+ return (implementation as IGLContextInternal).GetAddress(function);
+ }
+
#endregion
- #region IDisposable Members
+ #region --- IGLContextCreationHack Members ---
+
+ bool IGLContextCreationHack.SelectDisplayMode(DisplayMode mode, IWindowInfo info)
+ {
+ return (implementation as IGLContextCreationHack).SelectDisplayMode(mode, info);
+ }
+
+ void IGLContextCreationHack.SetWindowHandle(IntPtr handle)
+ {
+ (implementation as IGLContextCreationHack).SetWindowHandle(handle);
+ }
+
+ #endregion
+
+ #region --- IDisposable Members ---
///
/// Disposes of the GLContext.
///
public void Dispose()
{
- available_contexts.Remove(Context.ToInt64());
- implementation.Dispose();
+ this.Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ void Dispose(bool manual)
+ {
+ if (!disposed)
+ {
+ // TODO: Check if this is safe
+ //if (manual)
+ {
+ implementation.Dispose();
+ }
+ }
+ }
+
+ ~GLContext()
+ {
+ this.Dispose(false);
}
#endregion
}
}
+
+internal class ContextHandle : /*System.Runtime.InteropServices.SafeHandle,*/ IComparable
+{
+ IntPtr handle;
+ public IntPtr Handle { get { return handle; } }
+
+ public ContextHandle() /*: base(IntPtr.Zero, true)*/ { }
+ public ContextHandle(IntPtr h) { handle = h; }
+
+ #region IComparable Members
+
+ public int CompareTo(ContextHandle other)
+ {
+ unsafe { return (int)((int*)other.handle.ToPointer() - (int*)this.handle.ToPointer()); }
+ }
+
+ #endregion
+
+ public override string ToString()
+ {
+ return Handle.ToString();
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (obj is ContextHandle)
+ return this.Handle == ((ContextHandle)obj).Handle;
+ return false;
+ }
+
+ public override int GetHashCode()
+ {
+ return Handle.GetHashCode();
+ }
+
+ /*
+ public override bool IsInvalid
+ {
+ get { return handle == IntPtr.Zero; }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ throw new NotImplementedException();
+ }
+ */
+
+ public static implicit operator IntPtr(ContextHandle c)
+ {
+ return c.handle;
+ }
+
+ public static implicit operator ContextHandle(IntPtr p)
+ {
+ return new ContextHandle(p);
+ }
+
+
+
+}