diff --git a/Source/OpenTK/Graphics/GraphicsContext.cs b/Source/OpenTK/Graphics/GraphicsContext.cs
index 6c0b93f6..1fd39b2d 100644
--- a/Source/OpenTK/Graphics/GraphicsContext.cs
+++ b/Source/OpenTK/Graphics/GraphicsContext.cs
@@ -39,14 +39,13 @@ namespace OpenTK.Graphics
///
public sealed class GraphicsContext : IGraphicsContext, IGraphicsContextInternal
{
+ public delegate IntPtr GetAddressDelegate(string function);
+ public delegate ContextHandle GetCurrentContextDelegate();
+
#region --- Fields ---
IGraphicsContext implementation; // The actual render context implementation for the underlying platform.
bool disposed;
- // Indicates that this context was created through external means, e.g. Tao.Sdl or GLWidget#.
- // In this case, We'll assume that the external program will manage the lifetime of this
- // context - we'll not destroy it manually.
- readonly bool IsExternal;
bool check_errors = true;
// Cache for the context handle. We need this for RemoveContext()
// in case the user does not call Dispose(). When this happens,
@@ -67,17 +66,6 @@ namespace OpenTK.Graphics
#region --- Constructors ---
- // Necessary to allow creation of dummy GraphicsContexts (see CreateDummyContext static method).
- GraphicsContext(ContextHandle handle)
- {
- implementation = new OpenTK.Platform.Dummy.DummyGLContext(handle);
-
- lock (SyncRoot)
- {
- AddContext(this);
- }
- }
-
///
/// Constructs a new GraphicsContext with the specified GraphicsMode and attaches it to the specified window.
///
@@ -163,12 +151,65 @@ namespace OpenTK.Graphics
}
}
+ ///
+ /// Initializes a new instance of the class using
+ /// an external context handle that was created by a third-party library.
+ ///
+ ///
+ /// A valid, unique handle for an external OpenGL context, or ContextHandle.Zero to use the current context.
+ /// It is an error to specify a handle that has been created through OpenTK or that has been passed to OpenTK before.
+ ///
+ ///
+ /// A GetAddressDelegate instance that accepts the name of an OpenGL function and returns
+ /// a valid function pointer, or IntPtr.Zero if that function is not supported. This delegate should be
+ /// implemented using the same toolkit that created the OpenGL context (i.e. if the context was created with
+ /// SDL_GL_CreateContext(), then this delegate should use SDL_GL_GetProcAddress() to retrieve function
+ /// pointers.)
+ ///
+ ///
+ /// A GetCurrentContextDelegate instance that returns the handle of the current OpenGL context,
+ /// or IntPtr.Zero if no context is current on the calling thread. This delegate should be implemented
+ /// using the same toolkit that created the OpenGL context (i.e. if the context was created with
+ /// SDL_GL_CreateContext(), then this delegate should use SDL_GL_GetCurrentContext() to retrieve
+ /// the current context.)
+ ///
+ public GraphicsContext(ContextHandle handle, GetAddressDelegate getAddress, GetCurrentContextDelegate getCurrent)
+ {
+ if (getAddress == null || getCurrent == null)
+ throw new ArgumentNullException();
+
+ lock (SyncRoot)
+ {
+ // Replace a zero-handle by the current context, if any
+ if (handle == ContextHandle.Zero)
+ {
+ handle = getCurrent();
+ }
+
+ // Make sure this handle corresponds to a valid, unique OpenGL context
+ if (handle == ContextHandle.Zero)
+ {
+ throw new GraphicsContextMissingException();
+ }
+ else if (available_contexts.ContainsKey(handle))
+ {
+ throw new InvalidOperationException("Context handle has already been added");
+ }
+
+ // We have a valid handle for an external OpenGL context, wrap it into a
+ // DummyGLContext instance.
+ implementation = new Platform.Dummy.DummyGLContext(handle, getAddress);
+ GetCurrentContext = getCurrent ?? GetCurrentContext;
+ AddContext(this);
+ }
+ implementation.LoadAll();
+ }
+
///
/// Constructs a new GraphicsContext from a pre-existing context created outside of OpenTK.
///
/// The handle of the existing context. This must be a valid, unique handle that is not known to OpenTK.
- /// The window this context is bound to. This must be a valid window obtained through Utilities.CreateWindowInfo.
- /// Occurs if handle is identical to a context already registered with OpenTK.
+ /// This parameter is reserved.
public GraphicsContext(ContextHandle handle, IWindowInfo window)
: this(handle, window, null, 1, 0, GraphicsContextFlags.Default)
{ }
@@ -177,40 +218,14 @@ namespace OpenTK.Graphics
/// Constructs a new GraphicsContext from a pre-existing context created outside of OpenTK.
///
/// The handle of the existing context. This must be a valid, unique handle that is not known to OpenTK.
- /// The window this context is bound to. This must be a valid window obtained through Utilities.CreateWindowInfo.
- /// A different context that shares resources with this instance, if any.
- /// Pass null if the context is not shared or if this is the first GraphicsContext instruct you construct.
- /// The major version of the context (e.g. "2" for "2.1").
- /// The minor version of the context (e.g. "1" for "2.1").
- /// A bitwise combination of that describe this context.
- /// Occurs if handle is identical to a context already registered with OpenTK.
+ /// This parameter is reserved.
+ /// This parameter is reserved.
+ /// This parameter is reserved.
+ /// This parameter is reserved.
+ /// This parameter is reserved..
public GraphicsContext(ContextHandle handle, IWindowInfo window, IGraphicsContext shareContext, int major, int minor, GraphicsContextFlags flags)
- : this(handle)
- {
- lock (SyncRoot)
- {
- IsExternal = true;
-
- if (handle == ContextHandle.Zero)
- {
- implementation = new OpenTK.Platform.Dummy.DummyGLContext(handle);
- }
- else if (available_contexts.ContainsKey(handle))
- {
- throw new GraphicsContextException("Context already exists.");
- }
- else
- {
- switch ((flags & GraphicsContextFlags.Embedded) == GraphicsContextFlags.Embedded)
- {
- case false: implementation = Factory.Default.CreateGLContext(handle, window, shareContext, direct_rendering, major, minor, flags); break;
- case true: implementation = Factory.Embedded.CreateGLContext(handle, window, shareContext, direct_rendering, major, minor, flags); break;
- }
- }
-
- (this as IGraphicsContextInternal).LoadAll();
- }
- }
+ : this(handle, Platform.Utilities.CreateGetAddress(), Factory.Default.CreateGetCurrentGraphicsContext())
+ { }
#endregion
@@ -309,6 +324,7 @@ namespace OpenTK.Graphics
/// Instances created by this method will not be functional. Instance methods will have no effect.
/// This method requires that a context is current on the calling thread.
///
+ [Obsolete("Use GraphicsContext(ContextHandle, IWindowInfo) constructor instead")]
public static GraphicsContext CreateDummyContext()
{
ContextHandle handle = GetCurrentContext();
@@ -326,12 +342,13 @@ namespace OpenTK.Graphics
///
/// Instances created by this method will not be functional. Instance methods will have no effect.
///
+ [Obsolete("Use GraphicsContext(ContextHandle, IWindowInfo) constructor instead")]
public static GraphicsContext CreateDummyContext(ContextHandle handle)
{
if (handle == ContextHandle.Zero)
throw new ArgumentOutOfRangeException("handle");
- return new GraphicsContext(handle);
+ return new GraphicsContext(handle, (IWindowInfo)null);
}
#endregion
@@ -352,7 +369,6 @@ namespace OpenTK.Graphics
#region public static IGraphicsContext CurrentContext
- internal delegate ContextHandle GetCurrentContextDelegate();
internal static GetCurrentContextDelegate GetCurrentContext;
///