Removed Destroy event and RegisterForDisposal method from IGraphicsContext.

Added GraphicsContextBase, which acts as the foundation of all IGraphicsContext implementations.
Added DesktopGraphicsContext, which acts as the foundation of all desktop (i.e. not ES) IGraphicsContext implementations.
Modified all IGraphicsContext implementations to inherit from GraphicsContextBase and/or DesktopGraphicsContext.
This commit is contained in:
the_fiddler 2009-08-17 10:23:16 +00:00
parent 52263700fd
commit b1915d8ef3
10 changed files with 682 additions and 921 deletions

View file

@ -1,477 +1,425 @@
#region --- License --- #region --- License ---
/* Licensed under the MIT/X11 license. /* Licensed under the MIT/X11 license.
* Copyright (c) 2006-2008 the OpenTK Team. * Copyright (c) 2006-2008 the OpenTK Team.
* This notice may not be removed from any source distribution. * This notice may not be removed from any source distribution.
* See license.txt for licensing detailed licensing details. * See license.txt for licensing detailed licensing details.
*/ */
#endregion #endregion
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using System.Diagnostics; using System.Diagnostics;
using OpenTK.Platform; using OpenTK.Platform;
namespace OpenTK.Graphics namespace OpenTK.Graphics
{ {
/// <summary> /// <summary>
/// Represents and provides methods to manipulate an OpenGL render context. /// Represents and provides methods to manipulate an OpenGL render context.
/// </summary> /// </summary>
public sealed class GraphicsContext : IGraphicsContext, IGraphicsContextInternal public sealed class GraphicsContext : IGraphicsContext, IGraphicsContextInternal
{ {
#region --- Fields --- #region --- Fields ---
IGraphicsContext implementation; // The actual render context implementation for the underlying platform. IGraphicsContext implementation; // The actual render context implementation for the underlying platform.
List<IDisposable> dispose_queue = new List<IDisposable>(); List<IDisposable> dispose_queue = new List<IDisposable>();
bool disposed; bool disposed;
// Indicates that this context was created through external means, e.g. Tao.Sdl or GLWidget#. // 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 // In this case, We'll assume that the external program will manage the lifetime of this
// context - we'll not destroy it manually. // context - we'll not destroy it manually.
//bool is_external; //bool is_external;
bool check_errors = true; bool check_errors = true;
static bool share_contexts = true; static bool share_contexts = true;
static bool direct_rendering = true; static bool direct_rendering = true;
readonly static object context_lock = new object(); readonly static object context_lock = new object();
// Maps OS-specific context handles to GraphicsContext weak references. // Maps OS-specific context handles to GraphicsContext weak references.
readonly static Dictionary<ContextHandle, WeakReference> available_contexts = new Dictionary<ContextHandle, WeakReference>(); readonly static Dictionary<ContextHandle, WeakReference> available_contexts = new Dictionary<ContextHandle, WeakReference>();
#endregion #endregion
#region --- Constructors --- #region --- Constructors ---
static GraphicsContext() static GraphicsContext()
{ {
GetCurrentContext = Factory.Default.CreateGetCurrentGraphicsContext(); GetCurrentContext = Factory.Default.CreateGetCurrentGraphicsContext();
} }
// Necessary to allow creation of dummy GraphicsContexts (see CreateDummyContext static method). // Necessary to allow creation of dummy GraphicsContexts (see CreateDummyContext static method).
GraphicsContext(ContextHandle handle) GraphicsContext(ContextHandle handle)
{ {
implementation = new OpenTK.Platform.Dummy.DummyGLContext(handle); implementation = new OpenTK.Platform.Dummy.DummyGLContext(handle);
lock (context_lock) lock (context_lock)
{ {
available_contexts.Add((implementation as IGraphicsContextInternal).Context, new WeakReference(this)); available_contexts.Add((implementation as IGraphicsContextInternal).Context, new WeakReference(this));
} }
} }
/// <summary> /// <summary>
/// Constructs a new GraphicsContext with the specified GraphicsMode and attaches it to the specified window. /// Constructs a new GraphicsContext with the specified GraphicsMode and attaches it to the specified window.
/// </summary> /// </summary>
/// <param name="mode">The OpenTK.Graphics.GraphicsMode of the GraphicsContext.</param> /// <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="window">The OpenTK.Platform.IWindowInfo to attach the GraphicsContext to.</param>
public GraphicsContext(GraphicsMode mode, IWindowInfo window) public GraphicsContext(GraphicsMode mode, IWindowInfo window)
: this(mode, window, 1, 0, GraphicsContextFlags.Default) : this(mode, window, 1, 0, GraphicsContextFlags.Default)
{ } { }
/// <summary> /// <summary>
/// Constructs a new GraphicsContext with the specified GraphicsMode, version and flags, and attaches it to the specified window. /// Constructs a new GraphicsContext with the specified GraphicsMode, version and flags, and attaches it to the specified window.
/// </summary> /// </summary>
/// <param name="mode">The OpenTK.Graphics.GraphicsMode of the GraphicsContext.</param> /// <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="window">The OpenTK.Platform.IWindowInfo to attach the GraphicsContext to.</param>
/// <param name="major">The major version of the new GraphicsContext.</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="minor">The minor version of the new GraphicsContext.</param>
/// <param name="flags">The GraphicsContextFlags for the GraphicsContext.</param> /// <param name="flags">The GraphicsContextFlags for the GraphicsContext.</param>
/// <remarks> /// <remarks>
/// Different hardware supports different flags, major and minor versions. Invalid parameters will be silently ignored. /// Different hardware supports different flags, major and minor versions. Invalid parameters will be silently ignored.
/// </remarks> /// </remarks>
public GraphicsContext(GraphicsMode mode, IWindowInfo window, int major, int minor, GraphicsContextFlags flags) public GraphicsContext(GraphicsMode mode, IWindowInfo window, int major, int minor, GraphicsContextFlags flags)
{ {
bool designMode = false; bool designMode = false;
if (mode == null && window == null) if (mode == null && window == null)
designMode = true; designMode = true;
else if (mode == null) throw new ArgumentNullException("mode", "Must be a valid GraphicsMode."); 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."); else if (window == null) throw new ArgumentNullException("window", "Must point to a valid window.");
// Silently ignore invalid major and minor versions. // Silently ignore invalid major and minor versions.
if (major <= 0) if (major <= 0)
major = 1; major = 1;
if (minor < 0) if (minor < 0)
minor = 0; minor = 0;
Debug.Print("Creating GraphicsContext."); Debug.Print("Creating GraphicsContext.");
try try
{ {
Debug.Indent(); Debug.Indent();
Debug.Print("GraphicsMode: {0}", mode); Debug.Print("GraphicsMode: {0}", mode);
Debug.Print("IWindowInfo: {0}", window); Debug.Print("IWindowInfo: {0}", window);
Debug.Print("GraphicsContextFlags: {0}", flags); Debug.Print("GraphicsContextFlags: {0}", flags);
Debug.Print("Requested version: {0}.{1}", major, minor); Debug.Print("Requested version: {0}.{1}", major, minor);
IGraphicsContext shareContext = null; IGraphicsContext shareContext = null;
if (GraphicsContext.ShareContexts) if (GraphicsContext.ShareContexts)
{ {
lock (context_lock) lock (context_lock)
{ {
// A small hack to create a shared context with the first available context. // A small hack to create a shared context with the first available context.
foreach (WeakReference r in GraphicsContext.available_contexts.Values) foreach (WeakReference r in GraphicsContext.available_contexts.Values)
{ {
shareContext = (IGraphicsContext)r.Target; shareContext = (IGraphicsContext)r.Target;
break; break;
} }
} }
} }
// Todo: Add a DummyFactory implementing IPlatformFactory. // Todo: Add a DummyFactory implementing IPlatformFactory.
if (designMode) if (designMode)
implementation = new Platform.Dummy.DummyGLContext(); implementation = new Platform.Dummy.DummyGLContext();
else else
switch ((flags & GraphicsContextFlags.Embedded) == GraphicsContextFlags.Embedded) switch ((flags & GraphicsContextFlags.Embedded) == GraphicsContextFlags.Embedded)
{ {
case false: implementation = Factory.Default.CreateGLContext(mode, window, shareContext, direct_rendering, major, minor, flags); break; 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; case true: implementation = Factory.Embedded.CreateGLContext(mode, window, shareContext, direct_rendering, major, minor, flags); break;
} }
lock (context_lock) lock (context_lock)
{ {
available_contexts.Add((this as IGraphicsContextInternal).Context, new WeakReference(this)); available_contexts.Add((this as IGraphicsContextInternal).Context, new WeakReference(this));
} }
//(implementation as IGraphicsContextInternal).LoadAll(); //(implementation as IGraphicsContextInternal).LoadAll();
} }
finally finally
{ {
Debug.Unindent(); Debug.Unindent();
} }
} }
#endregion #endregion
#region --- Static Members --- #region --- Static Members ---
#region public static GraphicsContext CreateDummyContext() #region public static GraphicsContext CreateDummyContext()
/// <summary> /// <summary>
/// Creates a dummy GraphicsContext to allow OpenTK to work with contexts created by external libraries. /// Creates a dummy GraphicsContext to allow OpenTK to work with contexts created by external libraries.
/// </summary> /// </summary>
/// <returns>A new, dummy GraphicsContext instance.</returns> /// <returns>A new, dummy GraphicsContext instance.</returns>
/// <remarks> /// <remarks>
/// <para>Instances created by this methodwill not be functional. Instance methods will have no effect.</para> /// <para>Instances created by this methodwill not be functional. Instance methods will have no effect.</para>
/// </remarks> /// </remarks>
public static GraphicsContext CreateDummyContext() public static GraphicsContext CreateDummyContext()
{ {
ContextHandle handle = GetCurrentContext(); ContextHandle handle = GetCurrentContext();
if (handle == ContextHandle.Zero) if (handle == ContextHandle.Zero)
throw new InvalidOperationException("No GraphicsContext is current on the calling thread."); throw new InvalidOperationException("No GraphicsContext is current on the calling thread.");
return CreateDummyContext(handle); return CreateDummyContext(handle);
} }
public static GraphicsContext CreateDummyContext(ContextHandle handle) public static GraphicsContext CreateDummyContext(ContextHandle handle)
{ {
if (handle == ContextHandle.Zero) if (handle == ContextHandle.Zero)
throw new ArgumentOutOfRangeException("handle"); throw new ArgumentOutOfRangeException("handle");
return new GraphicsContext(handle); return new GraphicsContext(handle);
} }
#endregion #endregion
#region public static void Assert() #region public static void Assert()
/// <summary> /// <summary>
/// Checks if a GraphicsContext exists in the calling thread and throws a GraphicsContextException if it doesn't. /// Checks if a GraphicsContext exists in the calling thread and throws a GraphicsContextException if it doesn't.
/// </summary> /// </summary>
/// <exception cref="GraphicsContextMissingException">Generated when no GraphicsContext is current in the calling thread.</exception> /// <exception cref="GraphicsContextMissingException">Generated when no GraphicsContext is current in the calling thread.</exception>
public static void Assert() public static void Assert()
{ {
if (GraphicsContext.CurrentContext == null) if (GraphicsContext.CurrentContext == null)
throw new GraphicsContextMissingException(); throw new GraphicsContextMissingException();
} }
#endregion #endregion
#region public static IGraphicsContext CurrentContext #region public static IGraphicsContext CurrentContext
internal delegate ContextHandle GetCurrentContextDelegate(); internal delegate ContextHandle GetCurrentContextDelegate();
internal static GetCurrentContextDelegate GetCurrentContext; internal static GetCurrentContextDelegate GetCurrentContext;
/// <summary> /// <summary>
/// Gets the GraphicsContext that is current in the calling thread. /// Gets the GraphicsContext that is current in the calling thread.
/// </summary> /// </summary>
public static IGraphicsContext CurrentContext public static IGraphicsContext CurrentContext
{ {
get get
{ {
lock (context_lock) lock (context_lock)
{ {
if (available_contexts.Count > 0) if (available_contexts.Count > 0)
{ {
ContextHandle handle = GetCurrentContext(); ContextHandle handle = GetCurrentContext();
if (handle.Handle != IntPtr.Zero) if (handle.Handle != IntPtr.Zero)
return (GraphicsContext)available_contexts[handle].Target; return (GraphicsContext)available_contexts[handle].Target;
} }
return null; return null;
} }
} }
} }
#endregion #endregion
#region public static bool ShareContexts #region public static bool ShareContexts
/// <summary>Gets or sets a System.Boolean, indicating whether GraphicsContext resources are shared</summary> /// <summary>Gets or sets a System.Boolean, indicating whether GraphicsContext resources are shared</summary>
/// <remarks> /// <remarks>
/// <para>If ShareContexts is true, new GLContexts will share resources. If this value is /// <para>If ShareContexts is true, new GLContexts will share resources. If this value is
/// false, new GLContexts will not share resources.</para> /// false, new GLContexts will not share resources.</para>
/// <para>Changing this value will not affect already created GLContexts.</para> /// <para>Changing this value will not affect already created GLContexts.</para>
/// </remarks> /// </remarks>
public static bool ShareContexts { get { return share_contexts; } set { share_contexts = value; } } public static bool ShareContexts { get { return share_contexts; } set { share_contexts = value; } }
#endregion #endregion
#region public static bool DirectRendering #region public static bool DirectRendering
/// <summary>Gets or sets a System.Boolean, indicating whether GraphicsContexts will perform direct rendering.</summary> /// <summary>Gets or sets a System.Boolean, indicating whether GraphicsContexts will perform direct rendering.</summary>
/// <remarks> /// <remarks>
/// <para> /// <para>
/// If DirectRendering is true, new contexts will be constructed with direct rendering capabilities, if possible. /// 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. /// If DirectRendering is false, new contexts will be constructed with indirect rendering capabilities.
/// </para> /// </para>
/// <para>This property does not affect existing GraphicsContexts, unless they are recreated.</para> /// <para>This property does not affect existing GraphicsContexts, unless they are recreated.</para>
/// <para> /// <para>
/// This property is ignored on Operating Systems without support for indirect rendering, like Windows and OS X. /// This property is ignored on Operating Systems without support for indirect rendering, like Windows and OS X.
/// </para> /// </para>
/// </remarks> /// </remarks>
public static bool DirectRendering public static bool DirectRendering
{ {
get { return direct_rendering; } get { return direct_rendering; }
set { direct_rendering = value; } set { direct_rendering = value; }
} }
#endregion #endregion
#endregion #endregion
#region --- Private Members --- #region --- IGraphicsContext Members ---
#region void ContextDestroyed(IGraphicsContext context, EventArgs e) /// <summary>
/// Gets or sets a System.Boolean, indicating whether automatic error checking should be performed.
/// <summary> /// Influences the debug version of OpenTK.dll, only.
/// Handles the Destroy event. /// </summary>
/// </summary> /// <remarks>Automatic error checking will clear the OpenGL error state. Set CheckErrors to false if you use
/// <param name="context">The OpenTK.Platform.IGraphicsContext that was destroyed.</param> /// the OpenGL error state in your code flow (e.g. for checking supported texture formats).</remarks>
/// <param name="e">Not used.</param> public bool ErrorChecking
[Obsolete] {
void ContextDestroyed(IGraphicsContext context, EventArgs e) get { return check_errors; }
{ set { check_errors = value; }
this.Destroy -= ContextDestroyed; }
//available_contexts.Remove(((IGraphicsContextInternal)this).Context); /// <summary>
} /// Creates an OpenGL context with the specified direct/indirect rendering mode and sharing state with the
/// specified IGraphicsContext.
#endregion /// </summary>
/// <param name="direct">Set to true for direct rendering or false otherwise.</param>
#endregion /// <param name="source">The source IGraphicsContext to share state from.</param>.
/// <remarks>
#region --- IGraphicsContext Members --- /// <para>
/// Direct rendering is the default rendering mode for OpenTK, since it can provide higher performance
/// <summary> /// in some circumastances.
/// Gets or sets a System.Boolean, indicating whether automatic error checking should be performed. /// </para>
/// Influences the debug version of OpenTK.dll, only. /// <para>
/// </summary> /// The 'direct' parameter is a hint, and will ignored if the specified mode is not supported (e.g. setting
/// <remarks>Automatic error checking will clear the OpenGL error state. Set CheckErrors to false if you use /// indirect rendering on Windows platforms).
/// the OpenGL error state in your code flow (e.g. for checking supported texture formats).</remarks> /// </para>
public bool ErrorChecking /// </remarks>
{ void CreateContext(bool direct, IGraphicsContext source)
get { return check_errors; } {
set { check_errors = value; } lock (context_lock)
} {
/// <summary> available_contexts.Add((this as IGraphicsContextInternal).Context, new WeakReference(this));
/// Creates an OpenGL context with the specified direct/indirect rendering mode and sharing state with the }
/// specified IGraphicsContext. }
/// </summary>
/// <param name="direct">Set to true for direct rendering or false otherwise.</param> /// <summary>
/// <param name="source">The source IGraphicsContext to share state from.</param>. /// Swaps buffers on a context. This presents the rendered scene to the user.
/// <remarks> /// </summary>
/// <para> public void SwapBuffers()
/// Direct rendering is the default rendering mode for OpenTK, since it can provide higher performance {
/// in some circumastances. implementation.SwapBuffers();
/// </para> }
/// <para>
/// The 'direct' parameter is a hint, and will ignored if the specified mode is not supported (e.g. setting /// <summary>
/// indirect rendering on Windows platforms). /// Makes the GraphicsContext the current rendering target.
/// </para> /// </summary>
/// </remarks> /// <param name="window">A valid <see cref="OpenTK.Platform.IWindowInfo" /> structure.</param>
void CreateContext(bool direct, IGraphicsContext source) /// <remarks>
{ /// You can use this method to bind the GraphicsContext to a different window than the one it was created from.
this.Destroy += ContextDestroyed; /// </remarks>
public void MakeCurrent(IWindowInfo window)
lock (context_lock) {
{ implementation.MakeCurrent(window);
available_contexts.Add((this as IGraphicsContextInternal).Context, new WeakReference(this)); }
}
/// <summary>
//OpenTK.Graphics.OpenGL.GL.Clear(OpenTK.Graphics.OpenGL.ClearBufferMask.ColorBufferBit); /// Gets a System.Boolean indicating whether this Context is current in the calling thread.
//if (StaticGetCurrentContext == null) /// </summary>
// StaticGetCurrentContext = implementation.GetCurrentContext; public bool IsCurrent
} {
get { return implementation.IsCurrent; }
/// <summary> }
/// Swaps buffers on a context. This presents the rendered scene to the user.
/// </summary> /// <summary>
public void SwapBuffers() /// Gets or sets a value indicating whether VSync is enabled.
{ /// </summary>
implementation.SwapBuffers(); public bool VSync
} {
get { return implementation.VSync; }
/// <summary> set { implementation.VSync = value; }
/// Makes the GraphicsContext the current rendering target. }
/// </summary>
/// <param name="window">A valid <see cref="OpenTK.Platform.IWindowInfo" /> structure.</param> /// <summary>
/// <remarks> /// Updates the graphics context. This must be called when the render target
/// You can use this method to bind the GraphicsContext to a different window than the one it was created from. /// is resized for proper behavior on Mac OS X.
/// </remarks> /// </summary>
public void MakeCurrent(IWindowInfo window) /// <param name="window"></param>
{ public void Update(IWindowInfo window)
implementation.MakeCurrent(window); {
} implementation.Update(window);
}
/// <summary>
/// Gets a System.Boolean indicating whether this Context is current in the calling thread. #endregion
/// </summary>
public bool IsCurrent #region --- IGraphicsContextInternal Members ---
{
get { return implementation.IsCurrent; } /// <summary>
//set { implementation.IsCurrent = value; } /// Gets the platform-specific implementation of this IGraphicsContext.
} /// </summary>
IGraphicsContext IGraphicsContextInternal.Implementation
/// <summary> {
/// Raised when a Context is destroyed. get { return implementation; }
/// </summary> }
[Obsolete]
public event DestroyEvent<IGraphicsContext> Destroy /// <summary>
{ /// Loads all OpenGL extensions.
add { implementation.Destroy += value; } /// </summary>
remove { implementation.Destroy -= value; } /// <exception cref="OpenTK.Graphics.GraphicsContextException">
} /// Occurs when this instance is not the current GraphicsContext on the calling thread.
/// </exception>
/// <summary> void IGraphicsContextInternal.LoadAll()
/// Gets or sets a value indicating whether VSync is enabled. {
/// </summary> if (GraphicsContext.CurrentContext != this)
public bool VSync throw new GraphicsContextException();
{
get { return implementation.VSync; } (implementation as IGraphicsContextInternal).LoadAll();
set { implementation.VSync = value; } }
}
/// <summary>
/// <summary> /// Gets a handle to the OpenGL rendering context.
/// Updates the graphics context. This must be called when the render target /// </summary>
/// is resized for proper behavior on Mac OS X. ContextHandle IGraphicsContextInternal.Context
/// </summary> {
/// <param name="window"></param> get { return ((IGraphicsContextInternal)implementation).Context; }
public void Update(IWindowInfo window) }
{
implementation.Update(window); /// <summary>
} /// Gets the GraphicsMode of the context.
/// </summary>
#endregion public GraphicsMode GraphicsMode
{
#region --- IGraphicsContextInternal Members --- get { return (implementation as IGraphicsContext).GraphicsMode; }
}
/// <summary>
/// Gets the platform-specific implementation of this IGraphicsContext. /// <summary>
/// </summary> /// Gets the address of an OpenGL extension function.
IGraphicsContext IGraphicsContextInternal.Implementation /// </summary>
{ /// <param name="function">The name of the OpenGL function (e.g. "glGetString")</param>
get { return implementation; } /// <returns>
} /// A pointer to the specified function or IntPtr.Zero if the function isn't
/// available in the current opengl context.
/// <summary> /// </returns>
/// Loads all OpenGL extensions. IntPtr IGraphicsContextInternal.GetAddress(string function)
/// </summary> {
void IGraphicsContextInternal.LoadAll() return (implementation as IGraphicsContextInternal).GetAddress(function);
{ }
(implementation as IGraphicsContextInternal).LoadAll();
} #endregion
/// <summary> #region --- IDisposable Members ---
/// Gets a handle to the OpenGL rendering context.
/// </summary> /// <summary>
ContextHandle IGraphicsContextInternal.Context /// Disposes of the GraphicsContext.
{ /// </summary>
get { return ((IGraphicsContextInternal)implementation).Context; } public void Dispose()
} {
this.Dispose(true);
/// <summary> GC.SuppressFinalize(this);
/// Gets the GraphicsMode of the context. }
/// </summary>
public GraphicsMode GraphicsMode void Dispose(bool manual)
{ {
get { return (implementation as IGraphicsContext).GraphicsMode; } if (!disposed)
} {
Debug.Print("Disposing context {0}.", (this as IGraphicsContextInternal).Context.ToString());
/// <summary> lock (context_lock)
/// Registers an OpenGL resource for disposal. {
/// </summary> available_contexts.Remove((this as IGraphicsContextInternal).Context);
/// <param name="resource">The OpenGL resource to dispose.</param> }
void IGraphicsContextInternal.RegisterForDisposal(IDisposable resource)
{ if (manual)
GC.KeepAlive(resource); {
dispose_queue.Add(resource); if (implementation != null)
} implementation.Dispose();
}
/// <summary> disposed = true;
/// Disposes all registered OpenGL resources. }
/// </summary> }
void IGraphicsContextInternal.DisposeResources()
{ //~GraphicsContext()
foreach (IDisposable resource in dispose_queue) //{
resource.Dispose(); // this.Dispose(false);
//}
dispose_queue.Clear();
} #endregion
}
/// <summary> }
/// Gets the address of an OpenGL extension function.
/// </summary>
/// <param name="function">The name of the OpenGL function (e.g. "glGetString")</param>
/// <returns>
/// A pointer to the specified function or IntPtr.Zero if the function isn't
/// available in the current opengl context.
/// </returns>
IntPtr IGraphicsContextInternal.GetAddress(string function)
{
return (implementation as IGraphicsContextInternal).GetAddress(function);
}
#endregion
#region --- IDisposable Members ---
/// <summary>
/// Disposes of the GraphicsContext.
/// </summary>
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
}
}

View file

@ -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
}
}

View file

@ -33,12 +33,7 @@ namespace OpenTK.Graphics
/// <summary> /// <summary>
/// Gets or sets a System.Boolean indicating whether the GraphicsContext is current in the calling thread. /// Gets or sets a System.Boolean indicating whether the GraphicsContext is current in the calling thread.
/// </summary> /// </summary>
bool IsCurrent { get; /*set;*/ } bool IsCurrent { get; }
/// <summary>
/// Raised when a Context is destroyed.
/// </summary>
event DestroyEvent<IGraphicsContext> Destroy;
/// <summary> /// <summary>
/// Gets or sets a value indicating whether VSyncing is enabled. /// Gets or sets a value indicating whether VSyncing is enabled.
@ -91,25 +86,6 @@ namespace OpenTK.Graphics
/// </summary> /// </summary>
ContextHandle Context { get; } ContextHandle Context { get; }
/// <summary>
/// Registers an OpenGL resource for disposal.
/// </summary>
/// <param name="resource">The OpenGL resource to dispose.</param>
/// <remarks>
/// 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.
/// </remarks>
[Obsolete]
void RegisterForDisposal(IDisposable resource);
/// <summary>
/// Disposes all registered OpenGL resources.
/// </summary>
[Obsolete]
void DisposeResources();
/// <summary> /// <summary>
/// Gets the address of an OpenGL extension function. /// Gets the address of an OpenGL extension function.
/// </summary> /// </summary>

View file

@ -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<IGraphicsContext> 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
}
}

View file

@ -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();
}
}
}

View file

@ -17,45 +17,41 @@ namespace OpenTK.Platform.Dummy
/// An empty IGraphicsContext implementation to be used inside the Visual Studio designer. /// 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. /// This class supports OpenTK, and is not intended for use by OpenTK programs.
/// </summary> /// </summary>
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! // 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; bool vsync;
ContextHandle handle;
static int handle_count; static int handle_count;
#region --- Constructors --- #region --- Constructors ---
public DummyGLContext() 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) public DummyGLContext(ContextHandle handle)
{ {
this.handle = handle; Handle = handle;
} }
#endregion #endregion
#region --- IGraphicsContext Members --- #region --- IGraphicsContext Members ---
public IntPtr Context { get { return (IntPtr)handle_count; } }
public GraphicsMode GraphicsMode { get { return format; } }
public void CreateContext(bool direct, IGraphicsContext source) public void CreateContext(bool direct, IGraphicsContext source)
{ {
if (handle == ContextHandle.Zero) if (Handle == ContextHandle.Zero)
{ {
++handle_count; ++handle_count;
handle = new ContextHandle((IntPtr)handle_count); Handle = new ContextHandle((IntPtr)handle_count);
} }
} }
public void SwapBuffers() { } public override void SwapBuffers() { }
public void MakeCurrent(IWindowInfo info) { } public override void MakeCurrent(IWindowInfo info) { }
public bool IsCurrent { get { return true; } set { } } public override bool IsCurrent { get { return true; } }
[Obsolete] [Obsolete]
public event DestroyEvent<IGraphicsContext> Destroy; public event DestroyEvent<IGraphicsContext> Destroy;
@ -74,44 +70,26 @@ namespace OpenTK.Platform.Dummy
throw new NotImplementedException("Use the general GraphicsContext class instead."); throw new NotImplementedException("Use the general GraphicsContext class instead.");
} }
public IntPtr GetAddress(string function) { return IntPtr.Zero; } public override IntPtr GetAddress(string function) { return IntPtr.Zero; }
//public IEnumerable<DisplayMode> GetDisplayModes() { return null; }
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 #endregion
#region --- IDisposable Members --- #region --- IDisposable Members ---
public void Dispose() { } public override void Dispose() { }
#endregion
#region IGraphicsContextInternal Members
IGraphicsContext IGraphicsContextInternal.Implementation
{
get { return this; }
}
void IGraphicsContextInternal.LoadAll()
{
}
ContextHandle IGraphicsContextInternal.Context
{
get { return handle; }
}
#endregion #endregion
} }

View file

@ -33,13 +33,12 @@ using OpenTK.Platform.Windows;
namespace OpenTK.Platform.Egl namespace OpenTK.Platform.Egl
{ {
class EglContext : IGraphicsContext, IGraphicsContextInternal class EglContext : GraphicsContextBase
{ {
#region Fields #region Fields
EglWindowInfo WindowInfo; EglWindowInfo WindowInfo;
EGLContext context; EGLContext HandleAsEGLContext { get { return new EGLContext(Handle.Handle); } set { Handle = new ContextHandle(value.Handle.Value); } }
GraphicsMode mode;
bool vsync = true; // Default vsync value is defined as 1 (true) in EGL. bool vsync = true; // Default vsync value is defined as 1 (true) in EGL.
bool disposed = false; bool disposed = false;
@ -63,8 +62,8 @@ namespace OpenTK.Platform.Egl
WindowInfo = window; WindowInfo = window;
mode = new EglGraphicsMode().SelectGraphicsMode(mode.ColorFormat, mode.Depth, mode.Stencil, mode.Samples, mode.AccumulatorFormat, mode.Buffers, mode.Stereo); Mode = new EglGraphicsMode().SelectGraphicsMode(mode.ColorFormat, mode.Depth, mode.Stencil, mode.Samples, mode.AccumulatorFormat, mode.Buffers, mode.Stereo);
if (!mode.Index.HasValue) if (!Mode.Index.HasValue)
throw new GraphicsModeException("Invalid or unsupported GraphicsMode."); throw new GraphicsModeException("Invalid or unsupported GraphicsMode.");
EGLConfig config = new EGLConfig(mode.Index.Value); EGLConfig config = new EGLConfig(mode.Index.Value);
@ -72,7 +71,7 @@ namespace OpenTK.Platform.Egl
window.CreateWindowSurface(config); window.CreateWindowSurface(config);
int[] attrib_list = new int[] { Egl.CONTEXT_CLIENT_VERSION, major, Egl.NONE }; 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); MakeCurrent(window);
} }
@ -81,12 +80,12 @@ namespace OpenTK.Platform.Egl
#region IGraphicsContext Members #region IGraphicsContext Members
public void SwapBuffers() public override void SwapBuffers()
{ {
Egl.SwapBuffers(WindowInfo.Display, WindowInfo.Surface); 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, // 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, // 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)). // or the window it was constructed on (which may not be EGL)).
if (window is EglWindowInfo) if (window is EglWindowInfo)
WindowInfo = (EglWindowInfo)window; 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<IGraphicsContext> Destroy; public override bool VSync
public bool VSync
{ {
get 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! // Todo: implement this!
public bool ErrorChecking public bool ErrorChecking
{ {
@ -145,9 +132,25 @@ namespace OpenTK.Platform.Egl
#endregion #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 #region IDisposable Members
public void Dispose() public override void Dispose()
{ {
Dispose(true); Dispose(true);
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
@ -162,11 +165,11 @@ namespace OpenTK.Platform.Egl
if (manual) if (manual)
{ {
Egl.MakeCurrent(WindowInfo.Display, WindowInfo.Surface, WindowInfo.Surface, EGLContext.None); Egl.MakeCurrent(WindowInfo.Display, WindowInfo.Surface, WindowInfo.Surface, EGLContext.None);
Egl.DestroyContext(WindowInfo.Display, context); Egl.DestroyContext(WindowInfo.Display, HandleAsEGLContext);
} }
else 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; disposed = true;
} }
@ -178,42 +181,5 @@ namespace OpenTK.Platform.Egl
} }
#endregion #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
} }
} }

View file

@ -23,10 +23,8 @@ namespace OpenTK.Platform.MacOS
using AGLContext = IntPtr; using AGLContext = IntPtr;
using AGLPbuffer = IntPtr; using AGLPbuffer = IntPtr;
class AglContext : IGraphicsContext, IGraphicsContextInternal class AglContext : DesktopGraphicsContext
{ {
IntPtr contextRef;
bool mVSync = false; bool mVSync = false;
// Todo: keep track of which display adapter was specified when the context was created. // Todo: keep track of which display adapter was specified when the context was created.
// IntPtr displayID; // IntPtr displayID;
@ -44,7 +42,7 @@ namespace OpenTK.Platform.MacOS
this.carbonWindow = (CarbonWindowInfo)window; this.carbonWindow = (CarbonWindowInfo)window;
if (shareContext is AglContext) if (shareContext is AglContext)
shareContextRef = ((AglContext)shareContext).contextRef; shareContextRef = ((AglContext)shareContext).Handle.Handle;
CreateContext(mode, carbonWindow, shareContextRef, true); CreateContext(mode, carbonWindow, shareContextRef, true);
} }
@ -150,7 +148,7 @@ namespace OpenTK.Platform.MacOS
// create the context and share it with the share reference. // 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"); MyAGLReportError("aglCreateContext");
// Free the pixel format from memory. // Free the pixel format from memory.
@ -165,7 +163,7 @@ namespace OpenTK.Platform.MacOS
MakeCurrent(carbonWindow); MakeCurrent(carbonWindow);
Debug.Print("context: {0}", contextRef); Debug.Print("context: {0}", Handle.Handle);
} }
void SetBufferRect(CarbonWindowInfo carbonWindow) void SetBufferRect(CarbonWindowInfo carbonWindow)
@ -200,10 +198,10 @@ namespace OpenTK.Platform.MacOS
glrect[2] = rect.Width; glrect[2] = rect.Width;
glrect[3] = rect.Height; 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"); MyAGLReportError("aglSetInteger");
Agl.aglEnable(contextRef, Agl.ParameterNames.AGL_BUFFER_RECT); Agl.aglEnable(Handle.Handle, Agl.ParameterNames.AGL_BUFFER_RECT);
MyAGLReportError("aglEnable"); MyAGLReportError("aglEnable");
} }
@ -211,7 +209,7 @@ namespace OpenTK.Platform.MacOS
{ {
IntPtr windowPort = GetWindowPortForWindowInfo(carbonWindow); IntPtr windowPort = GetWindowPortForWindowInfo(carbonWindow);
Agl.aglSetDrawable(contextRef, windowPort); Agl.aglSetDrawable(Handle.Handle, windowPort);
MyAGLReportError("aglSetDrawable"); MyAGLReportError("aglSetDrawable");
@ -236,8 +234,8 @@ namespace OpenTK.Platform.MacOS
SetDrawable(carbonWindow); SetDrawable(carbonWindow);
SetBufferRect(carbonWindow); SetBufferRect(carbonWindow);
Agl.aglUpdateContext(contextRef); Agl.aglUpdateContext(Handle.Handle);
} }
void MyAGLReportError(string function) void MyAGLReportError(string function)
@ -254,7 +252,7 @@ namespace OpenTK.Platform.MacOS
internal void SetFullScreen(CarbonWindowInfo info) 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 // 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 // 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) internal void UnsetFullScreen(CarbonWindowInfo windowInfo)
{ {
Agl.aglSetDrawable(contextRef, IntPtr.Zero); Agl.aglSetDrawable(Handle.Handle, IntPtr.Zero);
SetDrawable(windowInfo); SetDrawable(windowInfo);
} }
@ -276,7 +274,7 @@ namespace OpenTK.Platform.MacOS
#region IGraphicsContext Members #region IGraphicsContext Members
bool firstSwap = false; bool firstSwap = false;
public void SwapBuffers() public override void SwapBuffers()
{ {
// this is part of the hack to avoid dropping the first frame when // this is part of the hack to avoid dropping the first frame when
// using multiple GLControls. // using multiple GLControls.
@ -286,41 +284,27 @@ namespace OpenTK.Platform.MacOS
firstSwap = true; firstSwap = true;
SetDrawable(carbonWindow); SetDrawable(carbonWindow);
Update(carbonWindow); Update(carbonWindow);
} }
Agl.aglSwapBuffers(contextRef); Agl.aglSwapBuffers(Handle.Handle);
MyAGLReportError("aglSwapBuffers"); 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"); MyAGLReportError("aglSetCurrentContext");
} }
public bool IsCurrent public override bool IsCurrent
{ {
get get
{ {
return (contextRef == Agl.aglGetCurrentContext()); return (Handle.Handle == Agl.aglGetCurrentContext());
} }
} }
[Obsolete] public override bool VSync
public event DestroyEvent<IGraphicsContext> Destroy;
[Obsolete]
void OnDestroy()
{
if (Destroy != null)
{
Debug.Print("Destroy handlers: {0}", Destroy.GetInvocationList().Length);
Destroy(this, EventArgs.Empty);
}
}
public bool VSync
{ {
get get
{ {
@ -330,22 +314,11 @@ namespace OpenTK.Platform.MacOS
{ {
int intVal = value ? 1 : 0; 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; mVSync = value;
} }
} }
GraphicsMode IGraphicsContext.GraphicsMode
{
get { return graphics_mode; }
}
public bool ErrorChecking
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
#endregion #endregion
@ -355,7 +328,7 @@ namespace OpenTK.Platform.MacOS
Dispose(false); Dispose(false);
} }
public void Dispose() public override void Dispose()
{ {
Dispose(true); Dispose(true);
} }
@ -363,10 +336,9 @@ namespace OpenTK.Platform.MacOS
void Dispose(bool disposing) void Dispose(bool disposing)
{ {
if (contextRef == IntPtr.Zero) if (Handle.Handle == IntPtr.Zero)
return; return;
OnDestroy();
Debug.Print("Disposing of AGL context."); Debug.Print("Disposing of AGL context.");
try try
@ -379,13 +351,13 @@ namespace OpenTK.Platform.MacOS
} }
Agl.aglSetCurrentContext(IntPtr.Zero); 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; return;
} }
@ -404,32 +376,12 @@ namespace OpenTK.Platform.MacOS
#region IGraphicsContextInternal Members #region IGraphicsContextInternal Members
IGraphicsContext IGraphicsContextInternal.Implementation public override void LoadAll()
{ {
get { return this; } new OpenTK.Graphics.OpenGL.GL().LoadAll();
} }
void IGraphicsContextInternal.LoadAll() private const string Library = "libdl.dylib";
{
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";
[DllImport(Library, EntryPoint = "NSIsSymbolNameDefined")] [DllImport(Library, EntryPoint = "NSIsSymbolNameDefined")]
private static extern bool NSIsSymbolNameDefined(string s); private static extern bool NSIsSymbolNameDefined(string s);
@ -438,7 +390,7 @@ namespace OpenTK.Platform.MacOS
[DllImport(Library, EntryPoint = "NSAddressOfSymbol")] [DllImport(Library, EntryPoint = "NSAddressOfSymbol")]
private static extern IntPtr NSAddressOfSymbol(IntPtr symbol); private static extern IntPtr NSAddressOfSymbol(IntPtr symbol);
IntPtr IGraphicsContextInternal.GetAddress(string function) public override IntPtr GetAddress(string function)
{ {
string fname = "_" + function; string fname = "_" + function;
if (!NSIsSymbolNameDefined(fname)) if (!NSIsSymbolNameDefined(fname))

View file

@ -24,15 +24,12 @@ namespace OpenTK.Platform.Windows
/// Provides methods to create and control an opengl context on the Windows platform. /// 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. /// This class supports OpenTK, and is not intended for use by OpenTK programs.
/// </summary> /// </summary>
internal sealed class WinGLContext : IGraphicsContext, IGraphicsContextInternal//, IGLContextCreationHack internal sealed class WinGLContext : DesktopGraphicsContext
{ {
ContextHandle renderContext;
static IntPtr opengl32Handle; static IntPtr opengl32Handle;
static bool wgl_loaded; static bool wgl_loaded;
const string opengl32Name = "OPENGL32.DLL"; const string opengl32Name = "OPENGL32.DLL";
GraphicsMode format;
//DisplayMode mode = null;
bool vsync_supported; bool vsync_supported;
bool disposed; bool disposed;
@ -60,7 +57,7 @@ namespace OpenTK.Platform.Windows
if (window.WindowHandle == IntPtr.Zero) if (window.WindowHandle == IntPtr.Zero)
throw new ArgumentException("window", "Must be a valid window."); 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.Print("OpenGL will be bound to handle: {0}", window.WindowHandle);
Debug.Write("Setting pixel format... "); Debug.Write("Setting pixel format... ");
@ -98,12 +95,12 @@ namespace OpenTK.Platform.Windows
} }
attributes.Add(0); attributes.Add(0);
renderContext = new ContextHandle( Handle = new ContextHandle(
Wgl.Arb.CreateContextAttribs( Wgl.Arb.CreateContextAttribs(
window.DeviceContext, window.DeviceContext,
sharedContext != null ? (sharedContext as IGraphicsContextInternal).Context.Handle : IntPtr.Zero, sharedContext != null ? (sharedContext as IGraphicsContextInternal).Context.Handle : IntPtr.Zero,
attributes.ToArray())); attributes.ToArray()));
if (renderContext == ContextHandle.Zero) if (Handle == ContextHandle.Zero)
Debug.Print("failed. (Error: {0})", Marshal.GetLastWin32Error()); Debug.Print("failed. (Error: {0})", Marshal.GetLastWin32Error());
else else
Debug.Print("success!"); Debug.Print("success!");
@ -112,25 +109,25 @@ namespace OpenTK.Platform.Windows
catch (NullReferenceException e) { Debug.Print(e.ToString()); } 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. // Failed to create GL3-level context, fall back to GL2.
Debug.Write("Falling back to GL2... "); Debug.Write("Falling back to GL2... ");
renderContext = new ContextHandle(Wgl.Imports.CreateContext(window.DeviceContext)); Handle = new ContextHandle(Wgl.Imports.CreateContext(window.DeviceContext));
if (renderContext == ContextHandle.Zero) if (Handle == ContextHandle.Zero)
renderContext = new ContextHandle(Wgl.Imports.CreateContext(window.DeviceContext)); Handle = new ContextHandle(Wgl.Imports.CreateContext(window.DeviceContext));
if (renderContext == ContextHandle.Zero) if (Handle == ContextHandle.Zero)
throw new GraphicsContextException( throw new GraphicsContextException(
String.Format("Context creation failed. Wgl.CreateContext() error: {0}.", String.Format("Context creation failed. Wgl.CreateContext() error: {0}.",
Marshal.GetLastWin32Error())); Marshal.GetLastWin32Error()));
} }
Debug.WriteLine(String.Format("success! (id: {0})", renderContext)); Debug.WriteLine(String.Format("success! (id: {0})", Handle));
if (sharedContext != null) if (sharedContext != null)
{ {
Debug.Print("Sharing state with context {0}", sharedContext.ToString()); 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 --- IGraphicsContext Members ---
#region public void SwapBuffers() #region SwapBuffers
public void SwapBuffers() public override void SwapBuffers()
{ {
if (!Functions.SwapBuffers(Wgl.GetCurrentDC())) if (!Functions.SwapBuffers(Wgl.GetCurrentDC()))
throw new GraphicsContextException(String.Format( throw new GraphicsContextException(String.Format(
@ -149,9 +146,9 @@ namespace OpenTK.Platform.Windows
#endregion #endregion
#region public void MakeCurrent(IWindowInfo window) #region MakeCurrent
public void MakeCurrent(IWindowInfo window) public override void MakeCurrent(IWindowInfo window)
{ {
bool success; bool success;
@ -159,8 +156,8 @@ namespace OpenTK.Platform.Windows
{ {
if (((WinWindowInfo)window).WindowHandle == IntPtr.Zero) if (((WinWindowInfo)window).WindowHandle == IntPtr.Zero)
throw new ArgumentException("window", "Must point to a valid window."); 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 else
success = Wgl.Imports.MakeCurrent(IntPtr.Zero, IntPtr.Zero); success = Wgl.Imports.MakeCurrent(IntPtr.Zero, IntPtr.Zero);
@ -172,21 +169,11 @@ namespace OpenTK.Platform.Windows
} }
#endregion #endregion
#region public bool IsCurrent #region IsCurrent
public bool IsCurrent public override bool IsCurrent
{ {
get { return Wgl.GetCurrentContext() == this.renderContext.Handle; } get { return Wgl.GetCurrentContext() == Handle.Handle; }
/*
set
{
if (value)
Wgl.MakeCurrent(this.deviceContext, this.renderContext);
else
Wgl.MakeCurrent(IntPtr.Zero, IntPtr.Zero);
}
*/
} }
#endregion #endregion
@ -196,7 +183,7 @@ namespace OpenTK.Platform.Windows
/// <summary> /// <summary>
/// Gets or sets a System.Boolean indicating whether SwapBuffer calls are synced to the screen refresh rate. /// Gets or sets a System.Boolean indicating whether SwapBuffer calls are synced to the screen refresh rate.
/// </summary> /// </summary>
public bool VSync public override bool VSync
{ {
get get
{ {
@ -211,49 +198,16 @@ namespace OpenTK.Platform.Windows
#endregion #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<IGraphicsContext> Destroy;
#endregion #endregion
#region --- IGLContextInternal Members --- #region --- IGLContextInternal Members ---
#region Implementation
IGraphicsContext IGraphicsContextInternal.Implementation
{
get { return this; }
}
#endregion
#region void LoadAll() #region void LoadAll()
void IGraphicsContextInternal.LoadAll() public override void LoadAll()
{ {
Wgl.LoadAll(); Wgl.LoadAll();
GL.LoadAll(); new GL().LoadAll();
vsync_supported = Wgl.Arb.SupportsExtension(this, "WGL_EXT_swap_control") && vsync_supported = Wgl.Arb.SupportsExtension(this, "WGL_EXT_swap_control") &&
Wgl.Load("wglGetSwapIntervalEXT") && Wgl.Load("wglSwapIntervalEXT"); Wgl.Load("wglGetSwapIntervalEXT") && Wgl.Load("wglSwapIntervalEXT");
@ -261,15 +215,6 @@ namespace OpenTK.Platform.Windows
#endregion #endregion
#region ContextHandle IGLContextInternal.Context
ContextHandle IGraphicsContextInternal.Context
{
get { return renderContext; }
}
#endregion
#region IWindowInfo IGLContextInternal.Info #region IWindowInfo IGLContextInternal.Info
/* /*
IWindowInfo IGraphicsContextInternal.Info IWindowInfo IGraphicsContextInternal.Info
@ -279,33 +224,15 @@ namespace OpenTK.Platform.Windows
*/ */
#endregion #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); return Wgl.Imports.GetProcAddress(function_string);
} }
#endregion #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 #endregion
#region --- Private Methods --- #region --- Private Methods ---
@ -370,7 +297,7 @@ namespace OpenTK.Platform.Windows
#region --- IDisposable Members --- #region --- IDisposable Members ---
public void Dispose() public override void Dispose()
{ {
Dispose(true); Dispose(true);
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
@ -387,7 +314,7 @@ namespace OpenTK.Platform.Windows
else else
{ {
Debug.Print("[Warning] OpenGL context {0} leaked. Did you forget to call IGraphicsContext.Dispose()?", Debug.Print("[Warning] OpenGL context {0} leaked. Did you forget to call IGraphicsContext.Dispose()?",
renderContext.Handle); Handle.Handle);
} }
disposed = true; disposed = true;
} }
@ -402,17 +329,14 @@ namespace OpenTK.Platform.Windows
private void DestroyContext() private void DestroyContext()
{ {
if (Destroy != null) if (Handle != ContextHandle.Zero)
Destroy(this, EventArgs.Empty);
if (renderContext != ContextHandle.Zero)
{ {
try try
{ {
// This will fail if the user calls Dispose() on thread X when the context is current on thread Y. // 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}", Debug.Print("Failed to destroy OpenGL context {0}. Error: {1}",
renderContext.ToString(), Marshal.GetLastWin32Error()); Handle.ToString(), Marshal.GetLastWin32Error());
} }
catch (AccessViolationException e) catch (AccessViolationException e)
{ {
@ -422,7 +346,7 @@ namespace OpenTK.Platform.Windows
Debug.WriteLine(e.ToString()); Debug.WriteLine(e.ToString());
Debug.Unindent(); Debug.Unindent();
} }
renderContext = ContextHandle.Zero; Handle = ContextHandle.Zero;
} }
} }

View file

@ -18,7 +18,7 @@ namespace OpenTK.Platform.X11
/// Provides methods to create and control an opengl context on the X11 platform. /// 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. /// This class supports OpenTK, and is not intended for use by OpenTK programs.
/// </summary> /// </summary>
internal sealed class X11GLContext : IGraphicsContext, IGraphicsContextInternal internal sealed class X11GLContext : DesktopGraphicsContext
{ {
ContextHandle context; ContextHandle context;
X11WindowInfo currentWindow; X11WindowInfo currentWindow;
@ -183,12 +183,10 @@ namespace OpenTK.Platform.X11
#region --- IGraphicsContext Members --- #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) if (currentWindow.Display == IntPtr.Zero || currentWindow.WindowHandle == IntPtr.Zero)
throw new InvalidOperationException( throw new InvalidOperationException(
String.Format("Window is invalid. Display ({0}), Handle ({1}).", currentWindow.Display, currentWindow.WindowHandle)); String.Format("Window is invalid. Display ({0}), Handle ({1}).", currentWindow.Display, currentWindow.WindowHandle));
@ -197,9 +195,9 @@ namespace OpenTK.Platform.X11
#endregion #endregion
#region public void MakeCurrent(IWindowInfo window) #region MakeCurrent
public void MakeCurrent(IWindowInfo window) public override void MakeCurrent(IWindowInfo window)
{ {
if (window == null) if (window == null)
{ {
@ -227,25 +225,18 @@ namespace OpenTK.Platform.X11
#endregion #endregion
#region public bool IsCurrent #region IsCurrent
public bool IsCurrent public override bool IsCurrent
{ {
get { return Glx.GetCurrentContext() == this.context.Handle; } 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 #endregion
#region public bool VSync #region VSync
public bool VSync public override bool VSync
{ {
get get
{ {
@ -265,69 +256,24 @@ namespace OpenTK.Platform.X11
#endregion #endregion
[Obsolete] #region GetAddress
public event DestroyEvent<IGraphicsContext> Destroy;
#region public IntPtr GetAddress(string function) public override IntPtr GetAddress(string function)
public IntPtr GetAddress(string function)
{ {
return Glx.GetProcAddress(function); return Glx.GetProcAddress(function);
} }
#endregion #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 #endregion
#region --- IGLContextInternal Members --- #region --- IGLContextInternal Members ---
#region Implementation #region LoadAll
IGraphicsContext IGraphicsContextInternal.Implementation public override void LoadAll()
{ {
get { return this; } new OpenTK.Graphics.OpenGL.GL().LoadAll();
}
#endregion
#region void LoadAll()
void IGraphicsContextInternal.LoadAll()
{
OpenTK.Graphics.OpenGL.GL.LoadAll();
Glx.LoadAll(); Glx.LoadAll();
vsync_supported = this.GetAddress("glXSwapIntervalSGI") != IntPtr.Zero; vsync_supported = this.GetAddress("glXSwapIntervalSGI") != IntPtr.Zero;
Debug.Print("Context supports vsync: {0}.", vsync_supported); Debug.Print("Context supports vsync: {0}.", vsync_supported);
@ -335,16 +281,6 @@ namespace OpenTK.Platform.X11
#endregion #endregion
#region ContextHandle IGLContextInternal.Context
ContextHandle IGraphicsContextInternal.Context
{
get { return context; }
/*private set { context = value; }*/
}
#endregion
#region IWindowInfo IGLContextInternal.Info #region IWindowInfo IGLContextInternal.Info
//IWindowInfo IGraphicsContextInternal.Info { get { return window; } } //IWindowInfo IGraphicsContextInternal.Info { get { return window; } }
@ -353,19 +289,9 @@ namespace OpenTK.Platform.X11
#endregion #endregion
#region --- Methods ---
void OnDestroy()
{
if (Destroy != null)
Destroy(this, EventArgs.Empty);
}
#endregion
#region --- IDisposable Members --- #region --- IDisposable Members ---
public void Dispose() public override void Dispose()
{ {
this.Dispose(true); this.Dispose(true);
GC.SuppressFinalize(this); GC.SuppressFinalize(this);