diff --git a/Source/OpenTK/Graphics/GraphicsContext.cs b/Source/OpenTK/Graphics/GraphicsContext.cs index 738f541b..9d815ae9 100644 --- a/Source/OpenTK/Graphics/GraphicsContext.cs +++ b/Source/OpenTK/Graphics/GraphicsContext.cs @@ -1,477 +1,425 @@ -#region --- License --- -/* Licensed under the MIT/X11 license. - * Copyright (c) 2006-2008 the OpenTK Team. - * This notice may not be removed from any source distribution. - * See license.txt for licensing detailed licensing details. - */ -#endregion - -using System; -using System.Collections.Generic; -using System.Text; -using System.Diagnostics; - -using OpenTK.Platform; - -namespace OpenTK.Graphics -{ - /// - /// Represents and provides methods to manipulate an OpenGL render context. - /// - public sealed class GraphicsContext : IGraphicsContext, IGraphicsContextInternal - { - #region --- Fields --- - - IGraphicsContext implementation; // The actual render context implementation for the underlying platform. - List dispose_queue = new List(); - 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. - //bool is_external; - bool check_errors = true; - - static bool share_contexts = true; - static bool direct_rendering = true; - readonly static object context_lock = new object(); - // Maps OS-specific context handles to GraphicsContext weak references. - readonly static Dictionary available_contexts = new Dictionary(); - - #endregion - - #region --- Constructors --- - - static GraphicsContext() - { - GetCurrentContext = Factory.Default.CreateGetCurrentGraphicsContext(); - } - - // Necessary to allow creation of dummy GraphicsContexts (see CreateDummyContext static method). - GraphicsContext(ContextHandle handle) - { - implementation = new OpenTK.Platform.Dummy.DummyGLContext(handle); - - lock (context_lock) - { - available_contexts.Add((implementation as IGraphicsContextInternal).Context, new WeakReference(this)); - } - } - - /// - /// Constructs a new GraphicsContext with the specified GraphicsMode and attaches it to the specified window. - /// - /// The OpenTK.Graphics.GraphicsMode of the GraphicsContext. - /// The OpenTK.Platform.IWindowInfo to attach the GraphicsContext to. - public GraphicsContext(GraphicsMode mode, IWindowInfo window) - : this(mode, window, 1, 0, GraphicsContextFlags.Default) - { } - - /// - /// Constructs a new GraphicsContext with the specified GraphicsMode, version and flags, and attaches it to the specified window. - /// - /// The OpenTK.Graphics.GraphicsMode of the GraphicsContext. - /// The OpenTK.Platform.IWindowInfo to attach the GraphicsContext to. - /// The major version of the new GraphicsContext. - /// The minor version of the new GraphicsContext. - /// The GraphicsContextFlags for the GraphicsContext. - /// - /// Different hardware supports different flags, major and minor versions. Invalid parameters will be silently ignored. - /// - public GraphicsContext(GraphicsMode mode, IWindowInfo window, int major, int minor, GraphicsContextFlags flags) - { - 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 = null; - if (GraphicsContext.ShareContexts) - { - lock (context_lock) - { - // A small hack to create a shared context with the first available context. - foreach (WeakReference r in GraphicsContext.available_contexts.Values) - { - shareContext = (IGraphicsContext)r.Target; - break; - } - } - } - - // Todo: Add a DummyFactory implementing IPlatformFactory. - if (designMode) - implementation = new Platform.Dummy.DummyGLContext(); - else - switch ((flags & GraphicsContextFlags.Embedded) == GraphicsContextFlags.Embedded) - { - case false: implementation = Factory.Default.CreateGLContext(mode, window, shareContext, direct_rendering, major, minor, flags); break; - case true: implementation = Factory.Embedded.CreateGLContext(mode, window, shareContext, direct_rendering, major, minor, flags); break; - } - - lock (context_lock) - { - available_contexts.Add((this as IGraphicsContextInternal).Context, new WeakReference(this)); - } - //(implementation as IGraphicsContextInternal).LoadAll(); - } - finally - { - Debug.Unindent(); - } - } - - #endregion - - #region --- Static Members --- - - #region public static GraphicsContext CreateDummyContext() - - /// - /// Creates a dummy GraphicsContext to allow OpenTK to work with contexts created by external libraries. - /// - /// A new, dummy GraphicsContext instance. - /// - /// Instances created by this methodwill not be functional. Instance methods will have no effect. - /// - public static GraphicsContext CreateDummyContext() - { - ContextHandle handle = GetCurrentContext(); - if (handle == ContextHandle.Zero) - throw new InvalidOperationException("No GraphicsContext is current on the calling thread."); - - return CreateDummyContext(handle); - } - - public static GraphicsContext CreateDummyContext(ContextHandle handle) - { - if (handle == ContextHandle.Zero) - throw new ArgumentOutOfRangeException("handle"); - - return new GraphicsContext(handle); - } - - #endregion - - #region public static void Assert() - - /// - /// Checks if a GraphicsContext exists in the calling thread and throws a GraphicsContextException if it doesn't. - /// - /// Generated when no GraphicsContext is current in the calling thread. - public static void Assert() - { - if (GraphicsContext.CurrentContext == null) - throw new GraphicsContextMissingException(); - } - - #endregion - - #region public static IGraphicsContext CurrentContext - - internal delegate ContextHandle GetCurrentContextDelegate(); - internal static GetCurrentContextDelegate GetCurrentContext; - - /// - /// Gets the GraphicsContext that is current in the calling thread. - /// - public static IGraphicsContext CurrentContext - { - get - { - lock (context_lock) - { - if (available_contexts.Count > 0) - { - ContextHandle handle = GetCurrentContext(); - if (handle.Handle != IntPtr.Zero) - return (GraphicsContext)available_contexts[handle].Target; - } - return null; - } - } - } - - #endregion - - #region public static bool ShareContexts - - /// Gets or sets a System.Boolean, indicating whether GraphicsContext resources are shared - /// - /// If ShareContexts is true, new GLContexts will share resources. If this value is - /// false, new GLContexts will not share resources. - /// Changing this value will not affect already created GLContexts. - /// - public static bool ShareContexts { get { return share_contexts; } set { share_contexts = value; } } - - #endregion - - #region public static bool DirectRendering - - /// Gets or sets a System.Boolean, indicating whether GraphicsContexts will perform direct rendering. - /// - /// - /// If DirectRendering is true, new contexts will be constructed with direct rendering capabilities, if possible. - /// If DirectRendering is false, new contexts will be constructed with indirect rendering capabilities. - /// - /// This property does not affect existing GraphicsContexts, unless they are recreated. - /// - /// This property is ignored on Operating Systems without support for indirect rendering, like Windows and OS X. - /// - /// - public static bool DirectRendering - { - get { return direct_rendering; } - set { direct_rendering = value; } - } - - #endregion - - #endregion - - #region --- Private Members --- - - #region void ContextDestroyed(IGraphicsContext context, EventArgs e) - - /// - /// Handles the Destroy event. - /// - /// The OpenTK.Platform.IGraphicsContext that was destroyed. - /// Not used. - [Obsolete] - void ContextDestroyed(IGraphicsContext context, EventArgs e) - { - this.Destroy -= ContextDestroyed; - //available_contexts.Remove(((IGraphicsContextInternal)this).Context); - } - - #endregion - - #endregion - - #region --- IGraphicsContext Members --- - - /// - /// Gets or sets a System.Boolean, indicating whether automatic error checking should be performed. - /// Influences the debug version of OpenTK.dll, only. - /// - /// Automatic error checking will clear the OpenGL error state. Set CheckErrors to false if you use - /// the OpenGL error state in your code flow (e.g. for checking supported texture formats). - public bool ErrorChecking - { - get { return check_errors; } - set { check_errors = value; } - } - /// - /// Creates an OpenGL context with the specified direct/indirect rendering mode and sharing state with the - /// specified IGraphicsContext. - /// - /// Set to true for direct rendering or false otherwise. - /// The source IGraphicsContext to share state from.. - /// - /// - /// Direct rendering is the default rendering mode for OpenTK, since it can provide higher performance - /// in some circumastances. - /// - /// - /// The 'direct' parameter is a hint, and will ignored if the specified mode is not supported (e.g. setting - /// indirect rendering on Windows platforms). - /// - /// - void CreateContext(bool direct, IGraphicsContext source) - { - this.Destroy += ContextDestroyed; - - lock (context_lock) - { - available_contexts.Add((this as IGraphicsContextInternal).Context, new WeakReference(this)); - } - - //OpenTK.Graphics.OpenGL.GL.Clear(OpenTK.Graphics.OpenGL.ClearBufferMask.ColorBufferBit); - //if (StaticGetCurrentContext == null) - // StaticGetCurrentContext = implementation.GetCurrentContext; - } - - /// - /// Swaps buffers on a context. This presents the rendered scene to the user. - /// - public void SwapBuffers() - { - implementation.SwapBuffers(); - } - - /// - /// Makes the GraphicsContext the current rendering target. - /// - /// A valid structure. - /// - /// You can use this method to bind the GraphicsContext to a different window than the one it was created from. - /// - public void MakeCurrent(IWindowInfo window) - { - implementation.MakeCurrent(window); - } - - /// - /// Gets a System.Boolean indicating whether this Context is current in the calling thread. - /// - public bool IsCurrent - { - get { return implementation.IsCurrent; } - //set { implementation.IsCurrent = value; } - } - - /// - /// Raised when a Context is destroyed. - /// - [Obsolete] - public event DestroyEvent Destroy - { - add { implementation.Destroy += value; } - remove { implementation.Destroy -= value; } - } - - /// - /// Gets or sets a value indicating whether VSync is enabled. - /// - public bool VSync - { - get { return implementation.VSync; } - set { implementation.VSync = value; } - } - - /// - /// Updates the graphics context. This must be called when the render target - /// is resized for proper behavior on Mac OS X. - /// - /// - public void Update(IWindowInfo window) - { - implementation.Update(window); - } - - #endregion - - #region --- IGraphicsContextInternal Members --- - - /// - /// Gets the platform-specific implementation of this IGraphicsContext. - /// - IGraphicsContext IGraphicsContextInternal.Implementation - { - get { return implementation; } - } - - /// - /// Loads all OpenGL extensions. - /// - void IGraphicsContextInternal.LoadAll() - { - (implementation as IGraphicsContextInternal).LoadAll(); - } - - /// - /// Gets a handle to the OpenGL rendering context. - /// - ContextHandle IGraphicsContextInternal.Context - { - get { return ((IGraphicsContextInternal)implementation).Context; } - } - - /// - /// Gets the GraphicsMode of the context. - /// - public GraphicsMode GraphicsMode - { - get { return (implementation as IGraphicsContext).GraphicsMode; } - } - - /// - /// Registers an OpenGL resource for disposal. - /// - /// The OpenGL resource to dispose. - void IGraphicsContextInternal.RegisterForDisposal(IDisposable resource) - { - GC.KeepAlive(resource); - dispose_queue.Add(resource); - } - - /// - /// Disposes all registered OpenGL resources. - /// - void IGraphicsContextInternal.DisposeResources() - { - foreach (IDisposable resource in dispose_queue) - resource.Dispose(); - - dispose_queue.Clear(); - } - - /// - /// 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 IGraphicsContextInternal.GetAddress(string function) - { - return (implementation as IGraphicsContextInternal).GetAddress(function); - } - - #endregion - - #region --- IDisposable Members --- - - /// - /// Disposes of the GraphicsContext. - /// - public void Dispose() - { - this.Dispose(true); - GC.SuppressFinalize(this); - } - - void Dispose(bool manual) - { - if (!disposed) - { - Debug.Print("Disposing context {0}.", (this as IGraphicsContextInternal).Context.ToString()); - lock (context_lock) - { - available_contexts.Remove((this as IGraphicsContextInternal).Context); - } - - if (manual) - { - if (implementation != null) - implementation.Dispose(); - } - disposed = true; - } - } - - //~GraphicsContext() - //{ - // this.Dispose(false); - //} - - #endregion - } -} +#region --- License --- +/* Licensed under the MIT/X11 license. + * Copyright (c) 2006-2008 the OpenTK Team. + * This notice may not be removed from any source distribution. + * See license.txt for licensing detailed licensing details. + */ +#endregion + +using System; +using System.Collections.Generic; +using System.Text; +using System.Diagnostics; + +using OpenTK.Platform; + +namespace OpenTK.Graphics +{ + /// + /// Represents and provides methods to manipulate an OpenGL render context. + /// + public sealed class GraphicsContext : IGraphicsContext, IGraphicsContextInternal + { + #region --- Fields --- + + IGraphicsContext implementation; // The actual render context implementation for the underlying platform. + List dispose_queue = new List(); + 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. + //bool is_external; + bool check_errors = true; + + static bool share_contexts = true; + static bool direct_rendering = true; + readonly static object context_lock = new object(); + // Maps OS-specific context handles to GraphicsContext weak references. + readonly static Dictionary available_contexts = new Dictionary(); + + #endregion + + #region --- Constructors --- + + static GraphicsContext() + { + GetCurrentContext = Factory.Default.CreateGetCurrentGraphicsContext(); + } + + // Necessary to allow creation of dummy GraphicsContexts (see CreateDummyContext static method). + GraphicsContext(ContextHandle handle) + { + implementation = new OpenTK.Platform.Dummy.DummyGLContext(handle); + + lock (context_lock) + { + available_contexts.Add((implementation as IGraphicsContextInternal).Context, new WeakReference(this)); + } + } + + /// + /// Constructs a new GraphicsContext with the specified GraphicsMode and attaches it to the specified window. + /// + /// The OpenTK.Graphics.GraphicsMode of the GraphicsContext. + /// The OpenTK.Platform.IWindowInfo to attach the GraphicsContext to. + public GraphicsContext(GraphicsMode mode, IWindowInfo window) + : this(mode, window, 1, 0, GraphicsContextFlags.Default) + { } + + /// + /// Constructs a new GraphicsContext with the specified GraphicsMode, version and flags, and attaches it to the specified window. + /// + /// The OpenTK.Graphics.GraphicsMode of the GraphicsContext. + /// The OpenTK.Platform.IWindowInfo to attach the GraphicsContext to. + /// The major version of the new GraphicsContext. + /// The minor version of the new GraphicsContext. + /// The GraphicsContextFlags for the GraphicsContext. + /// + /// Different hardware supports different flags, major and minor versions. Invalid parameters will be silently ignored. + /// + public GraphicsContext(GraphicsMode mode, IWindowInfo window, int major, int minor, GraphicsContextFlags flags) + { + 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 = null; + if (GraphicsContext.ShareContexts) + { + lock (context_lock) + { + // A small hack to create a shared context with the first available context. + foreach (WeakReference r in GraphicsContext.available_contexts.Values) + { + shareContext = (IGraphicsContext)r.Target; + break; + } + } + } + + // Todo: Add a DummyFactory implementing IPlatformFactory. + if (designMode) + implementation = new Platform.Dummy.DummyGLContext(); + else + switch ((flags & GraphicsContextFlags.Embedded) == GraphicsContextFlags.Embedded) + { + case false: implementation = Factory.Default.CreateGLContext(mode, window, shareContext, direct_rendering, major, minor, flags); break; + case true: implementation = Factory.Embedded.CreateGLContext(mode, window, shareContext, direct_rendering, major, minor, flags); break; + } + + lock (context_lock) + { + available_contexts.Add((this as IGraphicsContextInternal).Context, new WeakReference(this)); + } + //(implementation as IGraphicsContextInternal).LoadAll(); + } + finally + { + Debug.Unindent(); + } + } + + #endregion + + #region --- Static Members --- + + #region public static GraphicsContext CreateDummyContext() + + /// + /// Creates a dummy GraphicsContext to allow OpenTK to work with contexts created by external libraries. + /// + /// A new, dummy GraphicsContext instance. + /// + /// Instances created by this methodwill not be functional. Instance methods will have no effect. + /// + public static GraphicsContext CreateDummyContext() + { + ContextHandle handle = GetCurrentContext(); + if (handle == ContextHandle.Zero) + throw new InvalidOperationException("No GraphicsContext is current on the calling thread."); + + return CreateDummyContext(handle); + } + + public static GraphicsContext CreateDummyContext(ContextHandle handle) + { + if (handle == ContextHandle.Zero) + throw new ArgumentOutOfRangeException("handle"); + + return new GraphicsContext(handle); + } + + #endregion + + #region public static void Assert() + + /// + /// Checks if a GraphicsContext exists in the calling thread and throws a GraphicsContextException if it doesn't. + /// + /// Generated when no GraphicsContext is current in the calling thread. + public static void Assert() + { + if (GraphicsContext.CurrentContext == null) + throw new GraphicsContextMissingException(); + } + + #endregion + + #region public static IGraphicsContext CurrentContext + + internal delegate ContextHandle GetCurrentContextDelegate(); + internal static GetCurrentContextDelegate GetCurrentContext; + + /// + /// Gets the GraphicsContext that is current in the calling thread. + /// + public static IGraphicsContext CurrentContext + { + get + { + lock (context_lock) + { + if (available_contexts.Count > 0) + { + ContextHandle handle = GetCurrentContext(); + if (handle.Handle != IntPtr.Zero) + return (GraphicsContext)available_contexts[handle].Target; + } + return null; + } + } + } + + #endregion + + #region public static bool ShareContexts + + /// Gets or sets a System.Boolean, indicating whether GraphicsContext resources are shared + /// + /// If ShareContexts is true, new GLContexts will share resources. If this value is + /// false, new GLContexts will not share resources. + /// Changing this value will not affect already created GLContexts. + /// + public static bool ShareContexts { get { return share_contexts; } set { share_contexts = value; } } + + #endregion + + #region public static bool DirectRendering + + /// Gets or sets a System.Boolean, indicating whether GraphicsContexts will perform direct rendering. + /// + /// + /// If DirectRendering is true, new contexts will be constructed with direct rendering capabilities, if possible. + /// If DirectRendering is false, new contexts will be constructed with indirect rendering capabilities. + /// + /// This property does not affect existing GraphicsContexts, unless they are recreated. + /// + /// This property is ignored on Operating Systems without support for indirect rendering, like Windows and OS X. + /// + /// + public static bool DirectRendering + { + get { return direct_rendering; } + set { direct_rendering = value; } + } + + #endregion + + #endregion + + #region --- IGraphicsContext Members --- + + /// + /// Gets or sets a System.Boolean, indicating whether automatic error checking should be performed. + /// Influences the debug version of OpenTK.dll, only. + /// + /// Automatic error checking will clear the OpenGL error state. Set CheckErrors to false if you use + /// the OpenGL error state in your code flow (e.g. for checking supported texture formats). + public bool ErrorChecking + { + get { return check_errors; } + set { check_errors = value; } + } + /// + /// Creates an OpenGL context with the specified direct/indirect rendering mode and sharing state with the + /// specified IGraphicsContext. + /// + /// Set to true for direct rendering or false otherwise. + /// The source IGraphicsContext to share state from.. + /// + /// + /// Direct rendering is the default rendering mode for OpenTK, since it can provide higher performance + /// in some circumastances. + /// + /// + /// The 'direct' parameter is a hint, and will ignored if the specified mode is not supported (e.g. setting + /// indirect rendering on Windows platforms). + /// + /// + void CreateContext(bool direct, IGraphicsContext source) + { + lock (context_lock) + { + available_contexts.Add((this as IGraphicsContextInternal).Context, new WeakReference(this)); + } + } + + /// + /// Swaps buffers on a context. This presents the rendered scene to the user. + /// + public void SwapBuffers() + { + implementation.SwapBuffers(); + } + + /// + /// Makes the GraphicsContext the current rendering target. + /// + /// A valid structure. + /// + /// You can use this method to bind the GraphicsContext to a different window than the one it was created from. + /// + public void MakeCurrent(IWindowInfo window) + { + implementation.MakeCurrent(window); + } + + /// + /// Gets a System.Boolean indicating whether this Context is current in the calling thread. + /// + public bool IsCurrent + { + get { return implementation.IsCurrent; } + } + + /// + /// Gets or sets a value indicating whether VSync is enabled. + /// + public bool VSync + { + get { return implementation.VSync; } + set { implementation.VSync = value; } + } + + /// + /// Updates the graphics context. This must be called when the render target + /// is resized for proper behavior on Mac OS X. + /// + /// + public void Update(IWindowInfo window) + { + implementation.Update(window); + } + + #endregion + + #region --- IGraphicsContextInternal Members --- + + /// + /// Gets the platform-specific implementation of this IGraphicsContext. + /// + IGraphicsContext IGraphicsContextInternal.Implementation + { + get { return implementation; } + } + + /// + /// Loads all OpenGL extensions. + /// + /// + /// Occurs when this instance is not the current GraphicsContext on the calling thread. + /// + void IGraphicsContextInternal.LoadAll() + { + if (GraphicsContext.CurrentContext != this) + throw new GraphicsContextException(); + + (implementation as IGraphicsContextInternal).LoadAll(); + } + + /// + /// Gets a handle to the OpenGL rendering context. + /// + ContextHandle IGraphicsContextInternal.Context + { + get { return ((IGraphicsContextInternal)implementation).Context; } + } + + /// + /// Gets the GraphicsMode of the context. + /// + public GraphicsMode GraphicsMode + { + get { return (implementation as IGraphicsContext).GraphicsMode; } + } + + /// + /// 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 IGraphicsContextInternal.GetAddress(string function) + { + return (implementation as IGraphicsContextInternal).GetAddress(function); + } + + #endregion + + #region --- IDisposable Members --- + + /// + /// Disposes of the GraphicsContext. + /// + public void Dispose() + { + this.Dispose(true); + GC.SuppressFinalize(this); + } + + void Dispose(bool manual) + { + if (!disposed) + { + Debug.Print("Disposing context {0}.", (this as IGraphicsContextInternal).Context.ToString()); + lock (context_lock) + { + available_contexts.Remove((this as IGraphicsContextInternal).Context); + } + + if (manual) + { + if (implementation != null) + implementation.Dispose(); + } + disposed = true; + } + } + + //~GraphicsContext() + //{ + // this.Dispose(false); + //} + + #endregion + } +} diff --git a/Source/OpenTK/Graphics/GraphicsContextBase.cs b/Source/OpenTK/Graphics/GraphicsContextBase.cs new file mode 100644 index 00000000..8519f57a --- /dev/null +++ b/Source/OpenTK/Graphics/GraphicsContextBase.cs @@ -0,0 +1,85 @@ +#region License +// +// The Open Toolkit Library License +// +// Copyright (c) 2006 - 2009 the Open Toolkit library. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do +// so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// +#endregion + +using System; +using System.Collections.Generic; +using System.Text; +using OpenTK.Platform; + +namespace OpenTK.Graphics +{ + // Provides the foundation for all IGraphicsContext implementations. + abstract class GraphicsContextBase : IGraphicsContext, IGraphicsContextInternal + { + #region Fields + + protected ContextHandle Handle; + protected GraphicsMode Mode; + + #endregion + + #region IGraphicsContext Members + + public abstract void SwapBuffers(); + + public abstract void MakeCurrent(IWindowInfo window); + + public abstract bool IsCurrent { get; } + + public abstract bool VSync { get; set; } + + public virtual void Update(IWindowInfo window) { } + + public GraphicsMode GraphicsMode { get { return Mode; } } + + public bool ErrorChecking + { + get { throw new NotImplementedException(); } + set { throw new NotImplementedException(); } + } + + #endregion + + #region IGraphicsContextInternal Members + + public IGraphicsContext Implementation { get { return this; } } + + public abstract void LoadAll(); + + public ContextHandle Context { get { return Handle; } } + + public abstract IntPtr GetAddress(string function); + + #endregion + + #region IDisposable Members + + public abstract void Dispose(); + + #endregion + } +} diff --git a/Source/OpenTK/Graphics/IGraphicsContext.cs b/Source/OpenTK/Graphics/IGraphicsContext.cs index 2beb5b74..629c5c57 100644 --- a/Source/OpenTK/Graphics/IGraphicsContext.cs +++ b/Source/OpenTK/Graphics/IGraphicsContext.cs @@ -33,12 +33,7 @@ namespace OpenTK.Graphics /// /// Gets or sets a System.Boolean indicating whether the GraphicsContext is current in the calling thread. /// - bool IsCurrent { get; /*set;*/ } - - /// - /// Raised when a Context is destroyed. - /// - event DestroyEvent Destroy; + bool IsCurrent { get; } /// /// Gets or sets a value indicating whether VSyncing is enabled. @@ -91,25 +86,6 @@ namespace OpenTK.Graphics /// ContextHandle Context { get; } - /// - /// Registers an OpenGL resource for disposal. - /// - /// The OpenGL resource to dispose. - /// - /// You may not destroy OpenGL resources in finalizers, since they run in - /// a different thread. To avoid this problem, use this method to register - /// a resource for disposal during the finalizer call, and call DisposeResources() - /// from the main thread to dispose it. - /// - [Obsolete] - void RegisterForDisposal(IDisposable resource); - - /// - /// Disposes all registered OpenGL resources. - /// - [Obsolete] - void DisposeResources(); - /// /// Gets the address of an OpenGL extension function. /// diff --git a/Source/OpenTK/Platform/DesktopGLContext.cs b/Source/OpenTK/Platform/DesktopGLContext.cs deleted file mode 100644 index e805a2ca..00000000 --- a/Source/OpenTK/Platform/DesktopGLContext.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Diagnostics; -using OpenTK.Graphics; - -namespace OpenTK.Platform -{ - // Provides the foundation for all desktop IGraphicsContext implementations. - abstract class DesktopGraphicsContext : IGraphicsContext - { - #region IGraphicsContext Members - - public abstract void SwapBuffers(); - - public abstract void MakeCurrent(IWindowInfo window); - - public abstract bool IsCurrent { get; } - - public abstract event DestroyEvent Destroy; - - public abstract bool VSync { get; set; } - - public abstract void Update(IWindowInfo window); - - public abstract GraphicsMode GraphicsMode { get; } - - public abstract bool ErrorChecking { get; set; } - - #endregion - - #region IDisposable Members - - public abstract void Dispose(); - - #endregion - } -} diff --git a/Source/OpenTK/Platform/DesktopGraphicsContext.cs b/Source/OpenTK/Platform/DesktopGraphicsContext.cs new file mode 100644 index 00000000..f667fa70 --- /dev/null +++ b/Source/OpenTK/Platform/DesktopGraphicsContext.cs @@ -0,0 +1,44 @@ +#region License +// +// The Open Toolkit Library License +// +// Copyright (c) 2006 - 2009 the Open Toolkit library. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do +// so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// +#endregion + +using System; +using System.Collections.Generic; +using System.Text; +using System.Diagnostics; +using OpenTK.Graphics; + +namespace OpenTK.Platform +{ + // Provides the foundation for all desktop IGraphicsContext implementations. + abstract class DesktopGraphicsContext : GraphicsContextBase + { + public override void LoadAll() + { + new OpenTK.Graphics.OpenGL.GL().LoadAll(); + } + } +} diff --git a/Source/OpenTK/Platform/Dummy/DummyGLContext.cs b/Source/OpenTK/Platform/Dummy/DummyGLContext.cs index 137a9323..4f37962a 100644 --- a/Source/OpenTK/Platform/Dummy/DummyGLContext.cs +++ b/Source/OpenTK/Platform/Dummy/DummyGLContext.cs @@ -17,45 +17,41 @@ namespace OpenTK.Platform.Dummy /// An empty IGraphicsContext implementation to be used inside the Visual Studio designer. /// This class supports OpenTK, and is not intended for use by OpenTK programs. /// - internal sealed class DummyGLContext : IGraphicsContext, IGraphicsContextInternal + internal sealed class DummyGLContext : DesktopGraphicsContext { // This mode is not real. To receive a real mode we'd have to create a temporary context, which is not desirable! - GraphicsMode format = new GraphicsMode(new IntPtr(2), 32, 16, 0, 0, 0, 2, false); bool vsync; - ContextHandle handle; static int handle_count; #region --- Constructors --- public DummyGLContext() { - this.handle = new ContextHandle(new IntPtr(++handle_count)); + Handle = new ContextHandle(new IntPtr(++handle_count)); + Mode = new GraphicsMode(new IntPtr(2), 32, 16, 0, 0, 0, 2, false); } public DummyGLContext(ContextHandle handle) { - this.handle = handle; + Handle = handle; } #endregion #region --- IGraphicsContext Members --- - public IntPtr Context { get { return (IntPtr)handle_count; } } - public GraphicsMode GraphicsMode { get { return format; } } - public void CreateContext(bool direct, IGraphicsContext source) { - if (handle == ContextHandle.Zero) + if (Handle == ContextHandle.Zero) { ++handle_count; - handle = new ContextHandle((IntPtr)handle_count); + Handle = new ContextHandle((IntPtr)handle_count); } } - public void SwapBuffers() { } - public void MakeCurrent(IWindowInfo info) { } - public bool IsCurrent { get { return true; } set { } } + public override void SwapBuffers() { } + public override void MakeCurrent(IWindowInfo info) { } + public override bool IsCurrent { get { return true; } } [Obsolete] public event DestroyEvent Destroy; @@ -74,44 +70,26 @@ namespace OpenTK.Platform.Dummy throw new NotImplementedException("Use the general GraphicsContext class instead."); } - public IntPtr GetAddress(string function) { return IntPtr.Zero; } - //public IEnumerable GetDisplayModes() { return null; } + public override IntPtr GetAddress(string function) { return IntPtr.Zero; } - public bool VSync { get { return vsync; } set { vsync = value; } } + public override bool VSync { get { return vsync; } set { vsync = value; } } - public void Update(IWindowInfo window) + public override void Update(IWindowInfo window) + { } + + #endregion + + #region IGraphicsContextInternal Members + + public override void LoadAll() { } - public bool ErrorChecking - { - get { throw new NotImplementedException(); } - set { throw new NotImplementedException(); } - } - #endregion #region --- IDisposable Members --- - public void Dispose() { } - - #endregion - - #region IGraphicsContextInternal Members - - IGraphicsContext IGraphicsContextInternal.Implementation - { - get { return this; } - } - - void IGraphicsContextInternal.LoadAll() - { - } - - ContextHandle IGraphicsContextInternal.Context - { - get { return handle; } - } + public override void Dispose() { } #endregion } diff --git a/Source/OpenTK/Platform/Egl/EglContext.cs b/Source/OpenTK/Platform/Egl/EglContext.cs index d6faaa7d..2048b316 100644 --- a/Source/OpenTK/Platform/Egl/EglContext.cs +++ b/Source/OpenTK/Platform/Egl/EglContext.cs @@ -33,13 +33,12 @@ using OpenTK.Platform.Windows; namespace OpenTK.Platform.Egl { - class EglContext : IGraphicsContext, IGraphicsContextInternal + class EglContext : GraphicsContextBase { #region Fields EglWindowInfo WindowInfo; - EGLContext context; - GraphicsMode mode; + EGLContext HandleAsEGLContext { get { return new EGLContext(Handle.Handle); } set { Handle = new ContextHandle(value.Handle.Value); } } bool vsync = true; // Default vsync value is defined as 1 (true) in EGL. bool disposed = false; @@ -63,8 +62,8 @@ namespace OpenTK.Platform.Egl WindowInfo = window; - mode = new EglGraphicsMode().SelectGraphicsMode(mode.ColorFormat, mode.Depth, mode.Stencil, mode.Samples, mode.AccumulatorFormat, mode.Buffers, mode.Stereo); - if (!mode.Index.HasValue) + Mode = new EglGraphicsMode().SelectGraphicsMode(mode.ColorFormat, mode.Depth, mode.Stencil, mode.Samples, mode.AccumulatorFormat, mode.Buffers, mode.Stereo); + if (!Mode.Index.HasValue) throw new GraphicsModeException("Invalid or unsupported GraphicsMode."); EGLConfig config = new EGLConfig(mode.Index.Value); @@ -72,7 +71,7 @@ namespace OpenTK.Platform.Egl window.CreateWindowSurface(config); int[] attrib_list = new int[] { Egl.CONTEXT_CLIENT_VERSION, major, Egl.NONE }; - context = Egl.CreateContext(window.Display, config, shared != null ? shared.context : EGLContext.None, attrib_list); + HandleAsEGLContext = Egl.CreateContext(window.Display, config, shared != null ? shared.HandleAsEGLContext : EGLContext.None, attrib_list); MakeCurrent(window); } @@ -81,12 +80,12 @@ namespace OpenTK.Platform.Egl #region IGraphicsContext Members - public void SwapBuffers() + public override void SwapBuffers() { Egl.SwapBuffers(WindowInfo.Display, WindowInfo.Surface); } - public void MakeCurrent(IWindowInfo window) + public override void MakeCurrent(IWindowInfo window) { // Ignore 'window', unless it actually is an EGL window. In other words, // trying to make the EglContext current on a non-EGL window will do, @@ -94,17 +93,15 @@ namespace OpenTK.Platform.Egl // or the window it was constructed on (which may not be EGL)). if (window is EglWindowInfo) WindowInfo = (EglWindowInfo)window; - Egl.MakeCurrent(WindowInfo.Display, WindowInfo.Surface, WindowInfo.Surface, context); + Egl.MakeCurrent(WindowInfo.Display, WindowInfo.Surface, WindowInfo.Surface, HandleAsEGLContext); } - public bool IsCurrent + public override bool IsCurrent { - get { return Egl.GetCurrentContext().Handle == context.Handle; } + get { return Egl.GetCurrentContext().Handle == HandleAsEGLContext.Handle; } } - public event DestroyEvent Destroy; - - public bool VSync + public override bool VSync { get { @@ -121,16 +118,6 @@ namespace OpenTK.Platform.Egl } } - public void Update(IWindowInfo window) - { - // Do nothing. - } - - public GraphicsMode GraphicsMode - { - get { return mode; } - } - // Todo: implement this! public bool ErrorChecking { @@ -145,9 +132,25 @@ namespace OpenTK.Platform.Egl #endregion + #region IGraphicsContextInternal Members + + public override void LoadAll() + { + new OpenTK.Graphics.ES10.GL().LoadAll(); + new OpenTK.Graphics.ES11.GL().LoadAll(); + new OpenTK.Graphics.ES20.GL().LoadAll(); + } + + public override IntPtr GetAddress(string function) + { + return Egl.GetProcAddress(function); + } + + #endregion + #region IDisposable Members - public void Dispose() + public override void Dispose() { Dispose(true); GC.SuppressFinalize(this); @@ -162,11 +165,11 @@ namespace OpenTK.Platform.Egl if (manual) { Egl.MakeCurrent(WindowInfo.Display, WindowInfo.Surface, WindowInfo.Surface, EGLContext.None); - Egl.DestroyContext(WindowInfo.Display, context); + Egl.DestroyContext(WindowInfo.Display, HandleAsEGLContext); } else { - Debug.Print("[Warning] {0}:{1} was not disposed.", this.GetType().Name, context.Handle); + Debug.Print("[Warning] {0}:{1} was not disposed.", this.GetType().Name, HandleAsEGLContext.Handle); } disposed = true; } @@ -178,42 +181,5 @@ namespace OpenTK.Platform.Egl } #endregion - - #region IGraphicsContextInternal Members - - public IGraphicsContext Implementation - { - get { return this; } - } - - public void LoadAll() - { - // Todo: enable those - //OpenTK.Graphics.ES10.ES.LoadAll(); - OpenTK.Graphics.ES11.GL.LoadAll(); - //OpenTK.Graphics.ES20.ES.LoadAll(); - } - - public ContextHandle Context - { - get { return new ContextHandle(context.Handle.Value); } - } - - public void RegisterForDisposal(IDisposable resource) - { - throw new NotImplementedException(); - } - - public void DisposeResources() - { - throw new NotImplementedException(); - } - - public IntPtr GetAddress(string function) - { - return Egl.GetProcAddress(function); - } - - #endregion } } diff --git a/Source/OpenTK/Platform/MacOS/AglContext.cs b/Source/OpenTK/Platform/MacOS/AglContext.cs index 9e62568f..ff2e1c46 100644 --- a/Source/OpenTK/Platform/MacOS/AglContext.cs +++ b/Source/OpenTK/Platform/MacOS/AglContext.cs @@ -23,10 +23,8 @@ namespace OpenTK.Platform.MacOS using AGLContext = IntPtr; using AGLPbuffer = IntPtr; - class AglContext : IGraphicsContext, IGraphicsContextInternal + class AglContext : DesktopGraphicsContext { - IntPtr contextRef; - bool mVSync = false; // Todo: keep track of which display adapter was specified when the context was created. // IntPtr displayID; @@ -44,7 +42,7 @@ namespace OpenTK.Platform.MacOS this.carbonWindow = (CarbonWindowInfo)window; if (shareContext is AglContext) - shareContextRef = ((AglContext)shareContext).contextRef; + shareContextRef = ((AglContext)shareContext).Handle.Handle; CreateContext(mode, carbonWindow, shareContextRef, true); } @@ -150,7 +148,7 @@ namespace OpenTK.Platform.MacOS // create the context and share it with the share reference. - this.contextRef = Agl.aglCreateContext(myAGLPixelFormat, shareContextRef); + Handle = new ContextHandle( Agl.aglCreateContext(myAGLPixelFormat, shareContextRef)); MyAGLReportError("aglCreateContext"); // Free the pixel format from memory. @@ -165,7 +163,7 @@ namespace OpenTK.Platform.MacOS MakeCurrent(carbonWindow); - Debug.Print("context: {0}", contextRef); + Debug.Print("context: {0}", Handle.Handle); } void SetBufferRect(CarbonWindowInfo carbonWindow) @@ -200,10 +198,10 @@ namespace OpenTK.Platform.MacOS glrect[2] = rect.Width; glrect[3] = rect.Height; - Agl.aglSetInteger(contextRef, Agl.ParameterNames.AGL_BUFFER_RECT, glrect); + Agl.aglSetInteger(Handle.Handle, Agl.ParameterNames.AGL_BUFFER_RECT, glrect); MyAGLReportError("aglSetInteger"); - Agl.aglEnable(contextRef, Agl.ParameterNames.AGL_BUFFER_RECT); + Agl.aglEnable(Handle.Handle, Agl.ParameterNames.AGL_BUFFER_RECT); MyAGLReportError("aglEnable"); } @@ -211,7 +209,7 @@ namespace OpenTK.Platform.MacOS { IntPtr windowPort = GetWindowPortForWindowInfo(carbonWindow); - Agl.aglSetDrawable(contextRef, windowPort); + Agl.aglSetDrawable(Handle.Handle, windowPort); MyAGLReportError("aglSetDrawable"); @@ -236,8 +234,8 @@ namespace OpenTK.Platform.MacOS SetDrawable(carbonWindow); SetBufferRect(carbonWindow); - - Agl.aglUpdateContext(contextRef); + + Agl.aglUpdateContext(Handle.Handle); } void MyAGLReportError(string function) @@ -254,7 +252,7 @@ namespace OpenTK.Platform.MacOS internal void SetFullScreen(CarbonWindowInfo info) { - Agl.aglSetFullScreen(contextRef, 0, 0, 0, 0); + Agl.aglSetFullScreen(Handle.Handle, 0, 0, 0, 0); // This is a weird hack to workaround a bug where the first time a context // is made fullscreen, we just end up with a blank screen. So we undo it as fullscreen @@ -268,7 +266,7 @@ namespace OpenTK.Platform.MacOS } internal void UnsetFullScreen(CarbonWindowInfo windowInfo) { - Agl.aglSetDrawable(contextRef, IntPtr.Zero); + Agl.aglSetDrawable(Handle.Handle, IntPtr.Zero); SetDrawable(windowInfo); } @@ -276,7 +274,7 @@ namespace OpenTK.Platform.MacOS #region IGraphicsContext Members bool firstSwap = false; - public void SwapBuffers() + public override void SwapBuffers() { // this is part of the hack to avoid dropping the first frame when // using multiple GLControls. @@ -286,41 +284,27 @@ namespace OpenTK.Platform.MacOS firstSwap = true; SetDrawable(carbonWindow); Update(carbonWindow); - } + } - Agl.aglSwapBuffers(contextRef); + Agl.aglSwapBuffers(Handle.Handle); MyAGLReportError("aglSwapBuffers"); } - public void MakeCurrent(IWindowInfo window) + public override void MakeCurrent(IWindowInfo window) { - if (Agl.aglSetCurrentContext(contextRef) == false) + if (Agl.aglSetCurrentContext(Handle.Handle) == false) MyAGLReportError("aglSetCurrentContext"); } - public bool IsCurrent + public override bool IsCurrent { get { - return (contextRef == Agl.aglGetCurrentContext()); + return (Handle.Handle == Agl.aglGetCurrentContext()); } } - [Obsolete] - public event DestroyEvent Destroy; - - [Obsolete] - void OnDestroy() - { - - if (Destroy != null) - { - Debug.Print("Destroy handlers: {0}", Destroy.GetInvocationList().Length); - Destroy(this, EventArgs.Empty); - } - } - - public bool VSync + public override bool VSync { get { @@ -330,22 +314,11 @@ namespace OpenTK.Platform.MacOS { int intVal = value ? 1 : 0; - Agl.aglSetInteger(this.contextRef, Agl.ParameterNames.AGL_SWAP_INTERVAL, ref intVal); + Agl.aglSetInteger(Handle.Handle, Agl.ParameterNames.AGL_SWAP_INTERVAL, ref intVal); mVSync = value; } } - - GraphicsMode IGraphicsContext.GraphicsMode - { - get { return graphics_mode; } - } - - public bool ErrorChecking - { - get { throw new NotImplementedException(); } - set { throw new NotImplementedException(); } - } #endregion @@ -355,7 +328,7 @@ namespace OpenTK.Platform.MacOS Dispose(false); } - public void Dispose() + public override void Dispose() { Dispose(true); } @@ -363,10 +336,9 @@ namespace OpenTK.Platform.MacOS void Dispose(bool disposing) { - if (contextRef == IntPtr.Zero) + if (Handle.Handle == IntPtr.Zero) return; - OnDestroy(); Debug.Print("Disposing of AGL context."); try @@ -379,13 +351,13 @@ namespace OpenTK.Platform.MacOS } Agl.aglSetCurrentContext(IntPtr.Zero); - Agl.aglSetDrawable(contextRef, IntPtr.Zero); + Agl.aglSetDrawable(Handle.Handle, IntPtr.Zero); - Debug.Print("Set drawable to null for context {0}.", contextRef); + Debug.Print("Set drawable to null for context {0}.", Handle.Handle); - if (Agl.aglDestroyContext(contextRef) == true) + if (Agl.aglDestroyContext(Handle.Handle) == true) { - contextRef = IntPtr.Zero; + Handle = ContextHandle.Zero; return; } @@ -404,32 +376,12 @@ namespace OpenTK.Platform.MacOS #region IGraphicsContextInternal Members - IGraphicsContext IGraphicsContextInternal.Implementation + public override void LoadAll() { - get { return this; } + new OpenTK.Graphics.OpenGL.GL().LoadAll(); } - void IGraphicsContextInternal.LoadAll() - { - OpenTK.Graphics.OpenGL.GL.LoadAll(); - } - - ContextHandle IGraphicsContextInternal.Context - { - get { return (ContextHandle)contextRef; } - } - - void IGraphicsContextInternal.RegisterForDisposal(IDisposable resource) - { - throw new Exception("The method or operation is not implemented."); - } - - void IGraphicsContextInternal.DisposeResources() - { - throw new Exception("The method or operation is not implemented."); - } - - private const string Library = "libdl.dylib"; + private const string Library = "libdl.dylib"; [DllImport(Library, EntryPoint = "NSIsSymbolNameDefined")] private static extern bool NSIsSymbolNameDefined(string s); @@ -438,7 +390,7 @@ namespace OpenTK.Platform.MacOS [DllImport(Library, EntryPoint = "NSAddressOfSymbol")] private static extern IntPtr NSAddressOfSymbol(IntPtr symbol); - IntPtr IGraphicsContextInternal.GetAddress(string function) + public override IntPtr GetAddress(string function) { string fname = "_" + function; if (!NSIsSymbolNameDefined(fname)) diff --git a/Source/OpenTK/Platform/Windows/WinGLContext.cs b/Source/OpenTK/Platform/Windows/WinGLContext.cs index 6ea55c78..fcec4c72 100644 --- a/Source/OpenTK/Platform/Windows/WinGLContext.cs +++ b/Source/OpenTK/Platform/Windows/WinGLContext.cs @@ -24,15 +24,12 @@ namespace OpenTK.Platform.Windows /// Provides methods to create and control an opengl context on the Windows platform. /// This class supports OpenTK, and is not intended for use by OpenTK programs. /// - internal sealed class WinGLContext : IGraphicsContext, IGraphicsContextInternal//, IGLContextCreationHack + internal sealed class WinGLContext : DesktopGraphicsContext { - ContextHandle renderContext; static IntPtr opengl32Handle; static bool wgl_loaded; const string opengl32Name = "OPENGL32.DLL"; - GraphicsMode format; - //DisplayMode mode = null; bool vsync_supported; bool disposed; @@ -60,7 +57,7 @@ namespace OpenTK.Platform.Windows if (window.WindowHandle == IntPtr.Zero) throw new ArgumentException("window", "Must be a valid window."); - this.format = format; + Mode = format; Debug.Print("OpenGL will be bound to handle: {0}", window.WindowHandle); Debug.Write("Setting pixel format... "); @@ -98,12 +95,12 @@ namespace OpenTK.Platform.Windows } attributes.Add(0); - renderContext = new ContextHandle( + Handle = new ContextHandle( Wgl.Arb.CreateContextAttribs( window.DeviceContext, sharedContext != null ? (sharedContext as IGraphicsContextInternal).Context.Handle : IntPtr.Zero, attributes.ToArray())); - if (renderContext == ContextHandle.Zero) + if (Handle == ContextHandle.Zero) Debug.Print("failed. (Error: {0})", Marshal.GetLastWin32Error()); else Debug.Print("success!"); @@ -112,25 +109,25 @@ namespace OpenTK.Platform.Windows catch (NullReferenceException e) { Debug.Print(e.ToString()); } } - if (renderContext == ContextHandle.Zero) + if (Handle == ContextHandle.Zero) { // Failed to create GL3-level context, fall back to GL2. Debug.Write("Falling back to GL2... "); - renderContext = new ContextHandle(Wgl.Imports.CreateContext(window.DeviceContext)); - if (renderContext == ContextHandle.Zero) - renderContext = new ContextHandle(Wgl.Imports.CreateContext(window.DeviceContext)); - if (renderContext == ContextHandle.Zero) + Handle = new ContextHandle(Wgl.Imports.CreateContext(window.DeviceContext)); + if (Handle == ContextHandle.Zero) + Handle = new ContextHandle(Wgl.Imports.CreateContext(window.DeviceContext)); + if (Handle == ContextHandle.Zero) throw new GraphicsContextException( String.Format("Context creation failed. Wgl.CreateContext() error: {0}.", Marshal.GetLastWin32Error())); } - - Debug.WriteLine(String.Format("success! (id: {0})", renderContext)); + + Debug.WriteLine(String.Format("success! (id: {0})", Handle)); if (sharedContext != null) { Debug.Print("Sharing state with context {0}", sharedContext.ToString()); - Wgl.Imports.ShareLists((sharedContext as IGraphicsContextInternal).Context.Handle, renderContext.Handle); + Wgl.Imports.ShareLists((sharedContext as IGraphicsContextInternal).Context.Handle, Handle.Handle); } } @@ -138,9 +135,9 @@ namespace OpenTK.Platform.Windows #region --- IGraphicsContext Members --- - #region public void SwapBuffers() + #region SwapBuffers - public void SwapBuffers() + public override void SwapBuffers() { if (!Functions.SwapBuffers(Wgl.GetCurrentDC())) throw new GraphicsContextException(String.Format( @@ -149,9 +146,9 @@ namespace OpenTK.Platform.Windows #endregion - #region public void MakeCurrent(IWindowInfo window) + #region MakeCurrent - public void MakeCurrent(IWindowInfo window) + public override void MakeCurrent(IWindowInfo window) { bool success; @@ -159,8 +156,8 @@ namespace OpenTK.Platform.Windows { if (((WinWindowInfo)window).WindowHandle == IntPtr.Zero) throw new ArgumentException("window", "Must point to a valid window."); - - success = Wgl.Imports.MakeCurrent(((WinWindowInfo)window).DeviceContext, this.renderContext.Handle); + + success = Wgl.Imports.MakeCurrent(((WinWindowInfo)window).DeviceContext, Handle.Handle); } else success = Wgl.Imports.MakeCurrent(IntPtr.Zero, IntPtr.Zero); @@ -172,21 +169,11 @@ namespace OpenTK.Platform.Windows } #endregion - #region public bool IsCurrent + #region IsCurrent - public bool IsCurrent + public override bool IsCurrent { - get { return Wgl.GetCurrentContext() == this.renderContext.Handle; } - /* - set - { - if (value) - Wgl.MakeCurrent(this.deviceContext, this.renderContext); - else - Wgl.MakeCurrent(IntPtr.Zero, IntPtr.Zero); - } - */ - + get { return Wgl.GetCurrentContext() == Handle.Handle; } } #endregion @@ -196,7 +183,7 @@ namespace OpenTK.Platform.Windows /// /// Gets or sets a System.Boolean indicating whether SwapBuffer calls are synced to the screen refresh rate. /// - public bool VSync + public override bool VSync { get { @@ -211,49 +198,16 @@ namespace OpenTK.Platform.Windows #endregion - #region public void Update - public void Update(IWindowInfo window) - { - } - #endregion - - #region GraphicsMode IGLContext.GraphicsMode - - GraphicsMode IGraphicsContext.GraphicsMode - { - get { return format; } - } - - #endregion - - public bool ErrorChecking - { - get { throw new NotImplementedException(); } - set { throw new NotImplementedException(); } - } - - [Obsolete] - public event DestroyEvent Destroy; - #endregion #region --- IGLContextInternal Members --- - #region Implementation - - IGraphicsContext IGraphicsContextInternal.Implementation - { - get { return this; } - } - - #endregion - #region void LoadAll() - void IGraphicsContextInternal.LoadAll() + public override void LoadAll() { Wgl.LoadAll(); - GL.LoadAll(); + new GL().LoadAll(); vsync_supported = Wgl.Arb.SupportsExtension(this, "WGL_EXT_swap_control") && Wgl.Load("wglGetSwapIntervalEXT") && Wgl.Load("wglSwapIntervalEXT"); @@ -261,15 +215,6 @@ namespace OpenTK.Platform.Windows #endregion - #region ContextHandle IGLContextInternal.Context - - ContextHandle IGraphicsContextInternal.Context - { - get { return renderContext; } - } - - #endregion - #region IWindowInfo IGLContextInternal.Info /* IWindowInfo IGraphicsContextInternal.Info @@ -279,33 +224,15 @@ namespace OpenTK.Platform.Windows */ #endregion - #region public IntPtr GetAddress(string function_string) + #region GetAddress - public IntPtr GetAddress(string function_string) + public override IntPtr GetAddress(string function_string) { return Wgl.Imports.GetProcAddress(function_string); } #endregion - #region void IGLContextInternal.RegisterForDisposal(IDisposable resource) - - void IGraphicsContextInternal.RegisterForDisposal(IDisposable resource) - { - throw new NotSupportedException("Use OpenTK.GraphicsContext instead."); - } - - #endregion - - #region void IGLContextInternal.DisposeResources() - - void IGraphicsContextInternal.DisposeResources() - { - throw new NotSupportedException("Use OpenTK.GraphicsContext instead."); - } - - #endregion - #endregion #region --- Private Methods --- @@ -370,7 +297,7 @@ namespace OpenTK.Platform.Windows #region --- IDisposable Members --- - public void Dispose() + public override void Dispose() { Dispose(true); GC.SuppressFinalize(this); @@ -387,7 +314,7 @@ namespace OpenTK.Platform.Windows else { Debug.Print("[Warning] OpenGL context {0} leaked. Did you forget to call IGraphicsContext.Dispose()?", - renderContext.Handle); + Handle.Handle); } disposed = true; } @@ -402,17 +329,14 @@ namespace OpenTK.Platform.Windows private void DestroyContext() { - if (Destroy != null) - Destroy(this, EventArgs.Empty); - - if (renderContext != ContextHandle.Zero) + if (Handle != ContextHandle.Zero) { try { // 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)) + if (!Wgl.Imports.DeleteContext(Handle.Handle)) Debug.Print("Failed to destroy OpenGL context {0}. Error: {1}", - renderContext.ToString(), Marshal.GetLastWin32Error()); + Handle.ToString(), Marshal.GetLastWin32Error()); } catch (AccessViolationException e) { @@ -422,7 +346,7 @@ namespace OpenTK.Platform.Windows Debug.WriteLine(e.ToString()); Debug.Unindent(); } - renderContext = ContextHandle.Zero; + Handle = ContextHandle.Zero; } } diff --git a/Source/OpenTK/Platform/X11/X11GLContext.cs b/Source/OpenTK/Platform/X11/X11GLContext.cs index 5ba2d3d2..f53277a5 100644 --- a/Source/OpenTK/Platform/X11/X11GLContext.cs +++ b/Source/OpenTK/Platform/X11/X11GLContext.cs @@ -18,7 +18,7 @@ namespace OpenTK.Platform.X11 /// Provides methods to create and control an opengl context on the X11 platform. /// This class supports OpenTK, and is not intended for use by OpenTK programs. /// - internal sealed class X11GLContext : IGraphicsContext, IGraphicsContextInternal + internal sealed class X11GLContext : DesktopGraphicsContext { ContextHandle context; X11WindowInfo currentWindow; @@ -183,12 +183,10 @@ namespace OpenTK.Platform.X11 #region --- IGraphicsContext Members --- - #region public void SwapBuffers() + #region SwapBuffers() - public void SwapBuffers() + public override void SwapBuffers() { - //if (window == null) throw new ArgumentNullException("window", "Must point to a valid window."); - //X11WindowInfo w = (X11WindowInfo)window; if (currentWindow.Display == IntPtr.Zero || currentWindow.WindowHandle == IntPtr.Zero) throw new InvalidOperationException( String.Format("Window is invalid. Display ({0}), Handle ({1}).", currentWindow.Display, currentWindow.WindowHandle)); @@ -197,9 +195,9 @@ namespace OpenTK.Platform.X11 #endregion - #region public void MakeCurrent(IWindowInfo window) + #region MakeCurrent - public void MakeCurrent(IWindowInfo window) + public override void MakeCurrent(IWindowInfo window) { if (window == null) { @@ -227,25 +225,18 @@ namespace OpenTK.Platform.X11 #endregion - #region public bool IsCurrent + #region IsCurrent - public bool IsCurrent + public override bool IsCurrent { get { return Glx.GetCurrentContext() == this.context.Handle; } - //set - //{ - // if (value) - // Glx.MakeCurrent(window.Display, window.Handle, context); - // else - // Glx.MakeCurrent(window.Handle, IntPtr.Zero, IntPtr.Zero); - //} } #endregion - #region public bool VSync + #region VSync - public bool VSync + public override bool VSync { get { @@ -265,69 +256,24 @@ namespace OpenTK.Platform.X11 #endregion - [Obsolete] - public event DestroyEvent Destroy; + #region GetAddress - #region public IntPtr GetAddress(string function) - - public IntPtr GetAddress(string function) + public override IntPtr GetAddress(string function) { return Glx.GetProcAddress(function); } #endregion - #region public void Update - public void Update(IWindowInfo window) - { - } - #endregion - - #region public DisplayMode Mode - - GraphicsMode IGraphicsContext.GraphicsMode - { - get { return graphics_mode; } - } - - #endregion - - [Obsolete] - public void RegisterForDisposal(IDisposable resource) - { - throw new NotSupportedException("Use OpenTK.GraphicsContext instead."); - } - - [Obsolete] - public void DisposeResources() - { - throw new NotSupportedException("Use OpenTK.GraphicsContext instead."); - } - - public bool ErrorChecking - { - get { throw new NotImplementedException(); } - set { throw new NotImplementedException(); } - } - #endregion #region --- IGLContextInternal Members --- - #region Implementation + #region LoadAll - IGraphicsContext IGraphicsContextInternal.Implementation + public override void LoadAll() { - get { return this; } - } - - #endregion - - #region void LoadAll() - - void IGraphicsContextInternal.LoadAll() - { - OpenTK.Graphics.OpenGL.GL.LoadAll(); + new OpenTK.Graphics.OpenGL.GL().LoadAll(); Glx.LoadAll(); vsync_supported = this.GetAddress("glXSwapIntervalSGI") != IntPtr.Zero; Debug.Print("Context supports vsync: {0}.", vsync_supported); @@ -335,16 +281,6 @@ namespace OpenTK.Platform.X11 #endregion - #region ContextHandle IGLContextInternal.Context - - ContextHandle IGraphicsContextInternal.Context - { - get { return context; } - /*private set { context = value; }*/ - } - - #endregion - #region IWindowInfo IGLContextInternal.Info //IWindowInfo IGraphicsContextInternal.Info { get { return window; } } @@ -353,19 +289,9 @@ namespace OpenTK.Platform.X11 #endregion - #region --- Methods --- - - void OnDestroy() - { - if (Destroy != null) - Destroy(this, EventArgs.Empty); - } - - #endregion - #region --- IDisposable Members --- - public void Dispose() + public override void Dispose() { this.Dispose(true); GC.SuppressFinalize(this);