/////////////////////////////////////////////////////////////////////////////////////////////////////////// //TODO: review here, this is our custom OpenGLContext //eg, used with glfw GraphicsContext(OpenTK.Platform.External.ExternalGraphicsContext externalGraphicsContext) { implementation = externalGraphicsContext; 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; // } //} available_contexts.Add((implementation as IGraphicsContextInternal).Context, new WeakReference(this)); (this as IGraphicsContextInternal).LoadAll(); GetCurrentContextDelegate temp = externalGraphicsContext.CreateCurrentContextDel(); if (temp != null) { GetCurrentContext = temp; } } }
/// <summary> /// Initializes a new instance of the <see cref="OpenTK.Graphics.GraphicsContext"/> class using /// an external context handle that was created by a third-party library. /// </summary> /// <param name="handle"> /// A valid, unique handle for an external OpenGL context, or <c>ContextHandle.Zero</c> 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. /// </param> /// <param name="getAddress"> /// A <c>GetAddressDelegate</c> instance that accepts the name of an OpenGL function and returns /// a valid function pointer, or <c>IntPtr.Zero</c> 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.) /// </param> /// <param name="getCurrent"> /// A <c>GetCurrentContextDelegate</c> instance that returns the handle of the current OpenGL context, /// or <c>IntPtr.Zero</c> 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.) /// </param> 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(); }
GraphicsContext(OpenTK.Platform.External.ExternalGraphicsContext externalGraphicsContext) { implementation = externalGraphicsContext; lock (SyncRoot) { // Angle needs an embedded context //const GraphicsContextFlags useAngleFlag = GraphicsContextFlags.Angle // | GraphicsContextFlags.AngleD3D9 // | GraphicsContextFlags.AngleD3D11 // | GraphicsContextFlags.AngleOpenGL; bool useAngle = true; try { IsExternal = true; IPlatformFactory factory = Factory.Embedded; // Note: this approach does not allow us to mix native and EGL contexts in the same process. // This should not be a problem, as this use-case is not interesting for regular applications. // Note 2: some platforms may not support a direct way of getting the current context // (this happens e.g. with DummyGLContext). In that case, we use a slow fallback which // iterates through all known contexts and checks if any is current (check GetCurrentContext // declaration). if (GetCurrentContext == null) { GetCurrentContext = externalGraphicsContext.CreateCurrentContextDel(); // factory.CreateGetCurrentGraphicsContext(); } available_contexts.Add((implementation as IGraphicsContextInternal).Context, this); (this as IGraphicsContextInternal).LoadAll(); handle_cached = ((IGraphicsContextInternal)implementation).Context; factory.RegisterResource(this); } catch (Exception ex) { } } }
/// <summary> /// Constructs a new GraphicsContext with the specified GraphicsMode, version and flags, and attaches it to the specified window. /// </summary> /// <param name="mode">The OpenTK.Graphics.GraphicsMode of the GraphicsContext.</param> /// <param name="window">The OpenTK.Platform.IWindowInfo to attach the GraphicsContext to.</param> /// <param name="major">The major version of the new GraphicsContext.</param> /// <param name="minor">The minor version of the new GraphicsContext.</param> /// <param name="flags">The GraphicsContextFlags for the GraphicsContext.</param> /// <remarks> /// Different hardware supports different flags, major and minor versions. Invalid parameters will be silently ignored. /// </remarks> public GraphicsContext(GraphicsMode mode, IWindowInfo window, int major, int minor, GraphicsContextFlags flags) { lock (SyncRoot) { bool designMode = false; if (mode == null && window == null) { designMode = true; } else if (mode == null) { throw new ArgumentNullException("mode", "Must be a valid GraphicsMode."); } else if (window == null) { throw new ArgumentNullException("window", "Must point to a valid window."); } // Silently ignore invalid major and minor versions. if (major <= 0) { major = 1; } if (minor < 0) { minor = 0; } Debug.Print("Creating GraphicsContext."); try { Debug.Indent(); Debug.Print("GraphicsMode: {0}", mode); Debug.Print("IWindowInfo: {0}", window); Debug.Print("GraphicsContextFlags: {0}", flags); Debug.Print("Requested version: {0}.{1}", major, minor); IGraphicsContext shareContext = shareContext = FindSharedContext(); // Todo: Add a DummyFactory implementing IPlatformFactory. if (designMode) { implementation = new Platform.Dummy.DummyGLContext(); } else { IPlatformFactory factory = null; switch ((flags & GraphicsContextFlags.Embedded) == GraphicsContextFlags.Embedded) { case false: factory = Factory.Default; break; case true: factory = Factory.Embedded; break; } implementation = factory.CreateGLContext(mode, window, shareContext, direct_rendering, major, minor, flags); // Note: this approach does not allow us to mix native and EGL contexts in the same process. // This should not be a problem, as this use-case is not interesting for regular applications. // Note 2: some platforms may not support a direct way of getting the current context // (this happens e.g. with DummyGLContext). In that case, we use a slow fallback which // iterates through all known contexts and checks if any is current (check GetCurrentContext // declaration). if (GetCurrentContext == null) { GetCurrentContextDelegate temp = factory.CreateGetCurrentGraphicsContext(); if (temp != null) { GetCurrentContext = temp; } } } available_contexts.Add((this as IGraphicsContextInternal).Context, new WeakReference(this)); } finally { Debug.Unindent(); } } }
/// <summary> /// Initializes a new instance of the <see cref="OpenTK.Graphics.GraphicsContext"/> class using /// an external context handle that was created by a third-party library. /// </summary> /// <param name="handle"> /// A valid, unique handle for an external OpenGL context, or <c>ContextHandle.Zero</c> 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. /// </param> /// <param name="getAddress"> /// A <c>GetAddressDelegate</c> instance that accepts the name of an OpenGL function and returns /// a valid function pointer, or <c>IntPtr.Zero</c> 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.) /// </param> /// <param name="getCurrent"> /// A <c>GetCurrentContextDelegate</c> instance that returns the handle of the current OpenGL context, /// or <c>IntPtr.Zero</c> 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.) /// </param> public GraphicsContext(ContextHandle handle, GetAddressDelegate getAddress, GetCurrentContextDelegate getCurrent) { if (getAddress == null || getCurrent == null) throw new ArgumentNullException(); // Make sure OpenTK has been initialized. // Fixes https://github.com/opentk/opentk/issues/52 Toolkit.Init(); 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(); }
/// <summary> /// Constructs a new GraphicsContext with the specified GraphicsMode, version and flags, and attaches it to the /// specified window. A dummy context will be created if both /// the handle and the window are null. /// </summary> /// <param name="mode">The OpenTK.Graphics.GraphicsMode of the GraphicsContext.</param> /// <param name="window">The OpenTK.Platform.IWindowInfo to attach the GraphicsContext to.</param> /// <param name="shareContext">The GraphicsContext to share resources with, or null for explicit non-sharing.</param> /// <param name="major">The major version of the new GraphicsContext.</param> /// <param name="minor">The minor version of the new GraphicsContext.</param> /// <param name="flags">The GraphicsContextFlags for the GraphicsContext.</param> /// <remarks> /// Different hardware supports different flags, major and minor versions. Invalid parameters will be silently ignored. /// </remarks> public GraphicsContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, int major, int minor, GraphicsContextFlags flags) { lock (SyncRoot) { var designMode = false; if (mode == null && window == null) { designMode = true; } else if (mode == null) { throw new ArgumentNullException(nameof(mode), "Must be a valid GraphicsMode."); } else if (window == null) { throw new ArgumentNullException(nameof(window), "Must point to a valid window."); } // Silently ignore invalid major and minor versions. if (major <= 0) { major = 1; } if (minor < 0) { minor = 0; } // Angle needs an embedded context const GraphicsContextFlags useAngleFlag = GraphicsContextFlags.Angle | GraphicsContextFlags.AngleD3D9 | GraphicsContextFlags.AngleD3D11 | GraphicsContextFlags.AngleOpenGL; var useAngle = false; if ((flags & useAngleFlag) != 0) { flags |= GraphicsContextFlags.Embedded; useAngle = true; } Debug.Print("Creating GraphicsContext."); try { Debug.Indent(); Debug.Print("GraphicsMode: {0}", mode); Debug.Print("IWindowInfo: {0}", window); Debug.Print("GraphicsContextFlags: {0}", flags); Debug.Print("Requested version: {0}.{1}", major, minor); // Todo: Add a DummyFactory implementing IPlatformFactory. if (designMode) { implementation = new DummyGLContext(); } else { IPlatformFactory factory = null; switch ((flags & GraphicsContextFlags.Embedded) == GraphicsContextFlags.Embedded) { case false: factory = Factory.Default; break; case true: factory = useAngle ? Factory.Angle : Factory.Embedded; break; } // Note: this approach does not allow us to mix native and EGL contexts in the same process. // This should not be a problem, as this use-case is not interesting for regular applications. // Note 2: some platforms may not support a direct way of getting the current context // (this happens e.g. with DummyGLContext). In that case, we use a slow fallback which // iterates through all known contexts and checks if any is current (check GetCurrentContext // declaration). if (GetCurrentContext == null) { GetCurrentContext = factory.CreateGetCurrentGraphicsContext(); } implementation = factory.CreateGLContext(mode, window, shareContext, DirectRendering, major, minor, flags); handle_cached = ((IGraphicsContextInternal)implementation).Context; factory.RegisterResource(this); } AddContext(this); } finally { Debug.Unindent(); } } }