#region --- License --- /* Copyright (c) 2006, 2007 Stefanos Apostolopoulos * See license.txt for license info * * Date: 12/8/2007 * Time: 6:43 μμ */ #endregion using System; using System.Runtime.InteropServices; using System.Reflection; namespace OpenTK.Platform.Windows { /// /// /// public partial class Wgl { #region --- Constructors --- static Wgl() { assembly = Assembly.GetExecutingAssembly(); wglClass = assembly.GetType("OpenTK.Platform.Windows.Wgl"); delegatesClass = wglClass.GetNestedType("Delegates", BindingFlags.Static | BindingFlags.NonPublic); importsClass = wglClass.GetNestedType("Imports", BindingFlags.Static | BindingFlags.NonPublic); //LoadAll(); } #endregion #region --- Fields --- internal const string Library = "OPENGL32.DLL"; private static Assembly assembly; private static Type wglClass; private static Type delegatesClass; private static Type importsClass; private static bool reload_ext_extension_strings = true; private static bool reload_arb_extension_strings = true; #endregion #region public static Delegate GetDelegate(string name, Type signature) /// /// Creates a System.Delegate that can be used to call an OpenGL function, core or extension. /// /// The name of the Wgl function (eg. "wglNewList") /// The signature of the OpenGL function. /// /// A System.Delegate that can be used to call this OpenGL function, or null if the specified /// function name did not correspond to an OpenGL function. /// public static Delegate GetDelegate(string name, Type signature) { Delegate d; string realName = name.StartsWith("wgl") ? name.Substring(3) : name; if (importsClass.GetMethod(realName, BindingFlags.NonPublic | BindingFlags.Static) != null) { d = GetExtensionDelegate(name, signature) ?? Delegate.CreateDelegate(signature, typeof(Imports), realName); } else { d = GetExtensionDelegate(name, signature); } return d; } #endregion #region private static Delegate GetExtensionDelegate(string name, Type signature) /// /// Creates a System.Delegate that can be used to call a dynamically exported OpenGL function. /// /// The name of the OpenGL function (eg. "glNewList") /// The signature of the OpenGL function. /// /// A System.Delegate that can be used to call this OpenGL function or null /// if the function is not available in the current OpenGL context. /// private static Delegate GetExtensionDelegate(string name, Type signature) { IntPtr address = Imports.GetProcAddress(name); if (address == IntPtr.Zero || address == new IntPtr(1) || // Workaround for buggy nvidia drivers which return address == new IntPtr(2)) // 1 or 2 instead of IntPtr.Zero for some extensions. { return null; } else { return Marshal.GetDelegateForFunctionPointer(address, signature); } } #endregion #region public static void LoadAll() /// /// Loads all Wgl entry points, core and extensions. /// public static void LoadAll() { FieldInfo[] v = delegatesClass.GetFields(BindingFlags.Static | BindingFlags.NonPublic); foreach (FieldInfo f in v) { f.SetValue(null, GetDelegate(f.Name, f.FieldType)); } reload_ext_extension_strings = true; reload_arb_extension_strings = true; } #endregion #region public static bool Load(string function) /// /// Loads the given Wgl entry point. /// /// The name of the function to load. /// public static bool Load(string function) { FieldInfo f = delegatesClass.GetField(function, BindingFlags.Static | BindingFlags.NonPublic); if (f == null) return false; Delegate old = f.GetValue(null) as Delegate; Delegate @new = GetDelegate(f.Name, f.FieldType); if (old.Target != @new.Target) { f.SetValue(null, @new); if (function.EndsWith("EXT")) reload_ext_extension_strings = true; else if (function.EndsWith("ARB")) reload_arb_extension_strings = true; } return @new != null; } #endregion #region public static partial class ARB public static partial class ARB { private static string[] extensions; /// /// Checks if an "ARB" extension is supported by the given context. /// /// The device context. /// The extension to check. /// True if the extension is supported by the given context, false otherwise public static bool SupportsExtension(IntPtr deviceContext, string ext) { if (Wgl.Delegates.wglGetExtensionsStringARB != null) { if (extensions == null || reload_arb_extension_strings) { extensions = Wgl.ARB.GetExtensionsString(deviceContext).Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); Array.Sort(extensions); reload_arb_extension_strings = false; } return Array.BinarySearch(extensions, ext) != -1; } return false; } } #endregion #region public static partial class EXT public static partial class EXT { private static string[] extensions; /// /// Checks if an "EXT" extension is supported by the given context. /// /// The device context. /// The extension to check. /// True if the extension is supported by the given context, false otherwise public static bool SupportsExtension(IntPtr deviceContext, string ext) { if (Wgl.Delegates.wglGetExtensionsStringEXT != null) { if (extensions == null || reload_ext_extension_strings) { extensions = Wgl.ARB.GetExtensionsString(deviceContext).Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); Array.Sort(extensions); reload_ext_extension_strings = false; } return Array.BinarySearch(extensions, ext) != -1; } return false; } } #endregion } }