From 62d67917362c5777c901641fcd41aee59d645b41 Mon Sep 17 00:00:00 2001 From: parallels Date: Sat, 9 Nov 2013 18:50:53 +0100 Subject: [PATCH] Use glXGetProcAddressARB According to the Linux OpenGL ABI, glXGetProcAddressARB must be statically exported by libGL. This does *not* hold true for glXGetProcAddress. We must used the ARB version instead. Furthermore, glx entry points, unlike wgl, do not depend on any specific OpenGL context. This means we can load them in the constructor of the Glx class. --- Source/OpenTK/Platform/X11/Bindings/Glx.cs | 15 ++++++++++++++- Source/OpenTK/Platform/X11/GlxHelper.cs | 19 +++++++++++++++---- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/Source/OpenTK/Platform/X11/Bindings/Glx.cs b/Source/OpenTK/Platform/X11/Bindings/Glx.cs index 08e9e8c9..c5e3ccb6 100644 --- a/Source/OpenTK/Platform/X11/Bindings/Glx.cs +++ b/Source/OpenTK/Platform/X11/Bindings/Glx.cs @@ -352,7 +352,7 @@ namespace OpenTK.Platform.X11 public partial class Arb { - #region CreateContextAttribs + #region CreateContextAttri unsafe public static IntPtr CreateContextAttribs(IntPtr display, IntPtr fbconfig, IntPtr share_context, bool direct, int* attribs) { @@ -371,6 +371,19 @@ namespace OpenTK.Platform.X11 } #endregion + + #region GetProcAddress + + // The linux OpenGL ABI 3.6 (1999) requires + // that glXGetProcAddressARB be available as + // a static export. The same is *not* true + // for glXGetProcAddress, so we should use + // glXGetProcAddressARB instead. + // See http://www.opengl.org/registry/ABI/ + [DllImport(Library, EntryPoint = "glXGetProcAddressARB")] + public static extern IntPtr GetProcAddress([MarshalAs(UnmanagedType.LPTStr)] string procName); + + #endregion } internal static partial class Delegates diff --git a/Source/OpenTK/Platform/X11/GlxHelper.cs b/Source/OpenTK/Platform/X11/GlxHelper.cs index 3ec38c1b..36d4022f 100644 --- a/Source/OpenTK/Platform/X11/GlxHelper.cs +++ b/Source/OpenTK/Platform/X11/GlxHelper.cs @@ -20,17 +20,28 @@ namespace OpenTK.Platform.X11 const string Library = "libGL.so.1"; static readonly object sync_root = new object(); - // Disable BeforeFieldInit optimization. - static Glx() { } + static Glx() + { + // GLX entry points are not bound to a context. + // This means we can load them without creating + // a context first! (unlike WGL) + // See + // for more details. + Debug.WriteLine("Loading GLX entry points."); + new Glx().LoadEntryPoints(); + } protected override object SyncRoot { get { return sync_root; } } - protected override IntPtr GetAddress (string funcname) + protected override IntPtr GetAddress(string funcname) { - return Glx.GetProcAddress(funcname); + // We must use glXGetProcAddressARB, *not* + // glXGetProcAddress. See comment on function + // signature. + return Glx.Arb.GetProcAddress(funcname); } #if false