diff --git a/Source/Bind/Specifications/License.txt b/Source/Bind/Specifications/License.txt index 6bfc459d..fbe3177f 100644 --- a/Source/Bind/Specifications/License.txt +++ b/Source/Bind/Specifications/License.txt @@ -2,7 +2,7 @@ // // The Open Toolkit Library License // -// Copyright (c) 2006 - 2008 the Open Toolkit library, except where noted. +// 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 diff --git a/Source/Bind/Structures/Delegate.cs b/Source/Bind/Structures/Delegate.cs index 602776cc..fe682b4e 100644 --- a/Source/Bind/Structures/Delegate.cs +++ b/Source/Bind/Structures/Delegate.cs @@ -350,11 +350,7 @@ namespace Bind.Structures { // No special wrapper needed - just call this delegate: Function f = new Function(this); - - if (f.ReturnType.CurrentType.ToLower().Contains("void")) - f.Body.Add(String.Format("{0};", f.CallString())); - else - f.Body.Add(String.Format("return {0};", f.CallString())); + f.CreateBody(false); wrappers.Add(f); } diff --git a/Source/Bind/Structures/Function.cs b/Source/Bind/Structures/Function.cs index 8e34f2fb..6de13e14 100644 --- a/Source/Bind/Structures/Function.cs +++ b/Source/Bind/Structures/Function.cs @@ -36,6 +36,11 @@ namespace Bind.Structures static Regex endings = new Regex(@"((([df]|u?[isb])v?)|v)", RegexOptions.Compiled | RegexOptions.RightToLeft); static Regex endingsNotToTrim = new Regex("(ib|[tdrey]s|[eE]n[vd]|bled|Flagv|Tess|Status|Pixels)", RegexOptions.Compiled | RegexOptions.RightToLeft); + // Add a trailing v to functions matching this regex. Used to differntiate between overloads taking both + // a 'type' and a 'ref type' (such overloads are not CLS Compliant). + // The default Regex matches no functions. Create a new Regex in Bind.Generator classes to override the default behavior. + internal static Regex endingsAddV = new Regex("^0", RegexOptions.Compiled); + #endregion #region Fields @@ -44,15 +49,6 @@ namespace Bind.Structures int index; #endregion - - /// - /// Add a trailing v to functions matching this regex. Used to differntiate between overloads taking both - /// a 'type' and a 'ref type' (such overloads are not CLS Compliant). - /// - /// - /// The default Regex matches no functions. Create a new Regex in Bind.Generator classes to override the default behavior. - /// - internal static Regex endingsAddV = new Regex("^0", RegexOptions.Compiled); #region --- Constructors --- @@ -72,12 +68,16 @@ namespace Bind.Structures #endregion + #region public Delegate WrappedDelegate + public Delegate WrappedDelegate { get { return wrapped_delegate; } set { wrapped_delegate = value; } } + #endregion + #region public void TurnVoidPointersToIntPtr() public void TurnVoidPointersToIntPtr() @@ -394,10 +394,10 @@ namespace Bind.Structures #region public void CreateBody(bool wantCLSCompliance) - static List handle_statements = new List(); - static List handle_release_statements = new List(); - static List fixed_statements = new List(); - static List assign_statements = new List(); + readonly List handle_statements = new List(); + readonly List handle_release_statements = new List(); + readonly List fixed_statements = new List(); + readonly List assign_statements = new List(); public void CreateBody(bool wantCLSCompliance) { @@ -459,7 +459,21 @@ namespace Bind.Structures } } - if (!f.Unsafe || fixed_statements.Count > 0) + // Automatic OpenGL error checking. + // See OpenTK.Graphics.ErrorHelper for more information. + // Make sure that no error checking is added to the GetError function, + // as that would cause infinite recursion! + if (f.TrimmedName != "GetError") + { + f.Body.Add("#if DEBUG"); + f.Body.Add("using (new ErrorHelper(GraphicsContext.CurrentContext))"); + f.Body.Add("{"); + if (f.TrimmedName == "Begin") + f.Body.Add("GraphicsContext.CurrentContext.EnterBeginRegion();"); + f.Body.Add("#endif"); + } + + if (!f.Unsafe && fixed_statements.Count > 0) { f.Body.Add("unsafe"); f.Body.Add("{"); @@ -529,7 +543,7 @@ namespace Bind.Structures f.Body.Add("}"); } - if (!f.Unsafe || fixed_statements.Count > 0) + if (!f.Unsafe && fixed_statements.Count > 0) { f.Body.Unindent(); f.Body.Add("}"); @@ -541,6 +555,15 @@ namespace Bind.Structures f.Body.Add("}"); } + if (f.TrimmedName != "GetError") + { + f.Body.Add("#if DEBUG"); + if (f.TrimmedName == "End") + f.Body.Add("GraphicsContext.CurrentContext.ExitBeginRegion();"); + f.Body.Add("}"); + f.Body.Add("#endif"); + } + this.Body = f.Body; } diff --git a/Source/OpenTK/Graphics/GL/ErrorHelper.cs b/Source/OpenTK/Graphics/GL/ErrorHelper.cs new file mode 100644 index 00000000..b48ed4cd --- /dev/null +++ b/Source/OpenTK/Graphics/GL/ErrorHelper.cs @@ -0,0 +1,74 @@ +#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; + +namespace OpenTK.Graphics +{ + // Used in debug-mode only, for automatic OpenGL error-checking. + // + // Works like this: an instance is created before each OpenGL function is called. + // The constructor resets the OpenGL error state. Once the native function returns, + // the error state is checked again, raising the relevant exceptions. + // + // A using-region is used to ensure Dispose() is called. + // + // Make sure that no error checking is added to the GetError function, + // as that would cause infinite recursion! + struct ErrorHelper : IDisposable + { + #region Fields + + readonly GraphicsContext Context; + + #endregion + + #region Constructors + + public ErrorHelper(GraphicsContext context) + { + if (context == null) + throw new GraphicsContextMissingException(); + + Context = context; + Context.ResetErrors(); + } + + #endregion + + #region IDisposable Members + + public void Dispose() + { + Context.CheckErrors(); + } + + #endregion + } +} diff --git a/Source/OpenTK/Graphics/GL/GLHelper.cs b/Source/OpenTK/Graphics/GL/GLHelper.cs index 3e95f98e..28e7520f 100644 --- a/Source/OpenTK/Graphics/GL/GLHelper.cs +++ b/Source/OpenTK/Graphics/GL/GLHelper.cs @@ -266,7 +266,6 @@ namespace OpenTK.Graphics MethodInfo m; return GetExtensionDelegate(name, signature) ?? - /*((m = importsClass.GetMethod(name.Substring(2), BindingFlags.Static | BindingFlags.NonPublic)) != null ?*/ (Imports.FunctionMap.TryGetValue((name.Substring(2)), out m) ? Delegate.CreateDelegate(signature, m) : null); } diff --git a/Source/OpenTK/Graphics/GraphicsContext.cs b/Source/OpenTK/Graphics/GraphicsContext.cs index f576c70f..01f6c8cb 100644 --- a/Source/OpenTK/Graphics/GraphicsContext.cs +++ b/Source/OpenTK/Graphics/GraphicsContext.cs @@ -120,6 +120,8 @@ namespace OpenTK.Graphics #region --- Static Members --- + #region public static GraphicsContext CreateDummyContext() + /// /// Creates a dummy GraphicsContext to allow OpenTK to work with contexts created by external libraries. /// @@ -143,34 +145,27 @@ namespace OpenTK.Graphics #endregion - #region --- Private Members --- - - #region void ContextDestroyed(IGraphicsContext context, EventArgs e) + #region public static void Assert() /// - /// Handles the Destroy event. + /// Checks if a GraphicsContext exists in the calling thread and throws a GraphicsContextException if it doesn't. /// - /// The OpenTK.Platform.IGraphicsContext that was destroyed. - /// Not used. - void ContextDestroyed(IGraphicsContext context, EventArgs e) + /// Generated when no GraphicsContext is current in the calling thread. + public static void Assert() { - this.Destroy -= ContextDestroyed; - //available_contexts.Remove(((IGraphicsContextInternal)this).Context); + if (GraphicsContext.CurrentContext == null) + throw new GraphicsContextMissingException(); } #endregion - #endregion - - #region --- Public Members --- - #region public static IGraphicsContext CurrentContext internal delegate ContextHandle GetCurrentContextDelegate(); internal static GetCurrentContextDelegate GetCurrentContext; /// - /// Gets or sets the current GraphicsContext in the calling thread. + /// Gets the GraphicsContext that is current in the calling thread. /// public static GraphicsContext CurrentContext { @@ -187,13 +182,6 @@ namespace OpenTK.Graphics return null; } } - //set - //{ - // if (value != null) - // value.MakeCurrent(); - // else if (CurrentContext != null) - // CurrentContext.IsCurrent = false; - //} } #endregion @@ -231,20 +219,84 @@ namespace OpenTK.Graphics #endregion - #region public static AvailableDisplayFormats + #endregion + #region --- Internal Members --- + + bool inside_begin_region; + List error_list = new List(); + + // Indicates that we entered a GL.Begin() - GL.End() region. + [Conditional("DEBUG")] + internal void EnterBeginRegion() + { + inside_begin_region = true; + } + + // Indicates that we left a GL.Begin() - GL.End() region. + [Conditional("DEBUG")] + internal void ExitBeginRegion() + { + inside_begin_region = false; + } + + // Retrieve all OpenGL errors to clear the error list. + // See http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/geterror.html + [Conditional("DEBUG")] + internal void ResetErrors() + { + if (!inside_begin_region) + { + while (GL.GetError() != ErrorCode.NoError) + { } + } + } + + // Retrieve all OpenGL errors and throw an exception if anything other than NoError is returned. + [Conditional("DEBUG")] + internal void CheckErrors() + { + if (!inside_begin_region) + { + error_list.Clear(); + ErrorCode error; + do + { + error = GL.GetError(); + error_list.Add(error); + } while (error != ErrorCode.NoError); + + if (error_list.Count != 1) + { + StringBuilder sb = new StringBuilder(); + foreach (ErrorCode e in error_list) + { + sb.Append(e.ToString()); + sb.Append(", "); + } + sb.Remove(sb.Length - 2, 2); + + Debug.Assert(error_list.Count == 1, "OpenTK detected an OpenGL error.", + String.Format("The following errors where reported: \"{0}\"", sb.ToString())); + } + } + } #endregion - #region public static void Assert() + #region --- Private Members --- + + #region void ContextDestroyed(IGraphicsContext context, EventArgs e) /// - /// Checks if a GraphicsContext exists in the calling thread and throws a GraphicsContextException if it doesn't. + /// Handles the Destroy event. /// - public static void Assert() + /// The OpenTK.Platform.IGraphicsContext that was destroyed. + /// Not used. + void ContextDestroyed(IGraphicsContext context, EventArgs e) { - if (GraphicsContext.CurrentContext == null) - throw new GraphicsContextMissingException(); + this.Destroy -= ContextDestroyed; + //available_contexts.Remove(((IGraphicsContextInternal)this).Context); } #endregion @@ -344,60 +396,38 @@ namespace OpenTK.Graphics #region --- IGraphicsContextInternal Members --- - #region Implementation - + /// + /// Gets the platform-specific implementation of this IGraphicsContext. + /// IGraphicsContext IGraphicsContextInternal.Implementation { get { return implementation; } } - #endregion - - #region void LoadAll() - + /// + /// Loads all OpenGL extensions. + /// void IGraphicsContextInternal.LoadAll() { (implementation as IGraphicsContextInternal).LoadAll(); } - #endregion - - /// - /// Gets a handle to the OpenGL rendering context. + /// + /// Gets a handle to the OpenGL rendering context. + /// ContextHandle IGraphicsContextInternal.Context { get { return ((IGraphicsContextInternal)implementation).Context; } } - /* - /// - /// Gets the IWindowInfo describing the window associated with this context. - /// - IWindowInfo IGraphicsContextInternal.Info - { - get { return (implementation as IGraphicsContextInternal).Info; } - //internal set { (implementation as IGLContextInternal).Info = value; } - } - */ - /// /// Gets the GraphicsMode of the context. /// public GraphicsMode GraphicsMode { - get { return implementation.GraphicsMode; } + get { return (implementation as IGraphicsContextInternal).GraphicsMode; } } - ///// - ///// Gets a System.IntPtr containing the handle to the OpenGL context which is current in the - ///// calling thread, or IntPtr.Zero if no OpenGL context is current. - ///// - ///// A System.IntPtr that holds the handle to the current OpenGL context. - //ContextHandle IGLContextInternal.GetCurrentContext() - //{ - // return (implementation as IGLContextInternal).GetCurrentContext(); - //} - /// /// Registers an OpenGL resource for disposal. ///