add extensions

This commit is contained in:
Emmanuel 2020-09-10 16:23:24 +00:00
parent 522678c94d
commit fafd730d29
5 changed files with 64 additions and 72 deletions

View file

@ -59,6 +59,7 @@ namespace OpenTK
private IGraphicsContext _graphicsContext;
private IWindowInfo _windowInfo;
private bool _initialized;
private int swapInterval = 0;
#endregion
@ -92,6 +93,18 @@ namespace OpenTK
/// <summary>The minor version of OpenGL to use.</summary>
public int GLVersionMinor { get; set; }
public int SwapInterval
{
get => swapInterval; set
{
swapInterval = value;
if (GraphicsContext != null)
{
GraphicsContext.SwapInterval = value;
}
}
}
public GraphicsContextFlags GraphicsContextFlags
{
get;
@ -266,6 +279,8 @@ namespace OpenTK
{
_initialized = true;
Gdk.GLContext.ClearCurrent();
// If this looks uninitialized... initialize.
if (ColorBPP == 0)
{
@ -326,6 +341,10 @@ namespace OpenTK
OnGraphicsContextInitialized();
}
GraphicsContext.SwapInterval = SwapInterval;
var swap = GraphicsContext.SwapInterval;
OnInitialized();
}

View file

@ -41,38 +41,7 @@ namespace OpenTK.Platform
Stopwatch time = Stopwatch.StartNew();
Assembly assembly;
try
{
assembly = Assembly.Load("OpenTK.Graphics");
}
catch
{
// Failed to load graphics, oh well.
// Up to the user I guess?
// TODO: Should we expose this load failure to the user better?
return;
}
var provider = new GTKBindingHelper();
void LoadBindings(string typeNamespace)
{
var type = assembly.GetType($"OpenTK.Graphics.{typeNamespace}.GL");
if (type == null)
{
return;
}
var load = type.GetMethod("LoadBindings");
load.Invoke(null, new object[] { provider });
}
LoadBindings("ES11");
LoadBindings("ES20");
LoadBindings("ES30");
LoadBindings("OpenGL");
LoadBindings("OpenGL4");
GTKBindingHelper.InitializeGlBindings();
Debug.Print("Bindings loaded in {0} ms.", time.Elapsed.TotalMilliseconds);
}

View file

@ -253,7 +253,7 @@ namespace OpenTK.Platform.X11
/// <summary>
/// Provides access to GLX functions.
/// </summary>
internal class Glx : Graphics.GraphicsBindingsBase
internal unsafe class Glx : Graphics.GraphicsBindingsBase
{
private const string Library = "libGL.so.1";
private static readonly object sync_root = new object();
@ -314,31 +314,45 @@ namespace OpenTK.Platform.X11
{
for (int i = 0; i < _EntryPointsInstance.Length; i++)
{
_EntryPointsInstance[i] = Arb.GetProcAddress(new IntPtr(name + _EntryPointNameOffsetsInstance[i]));
_EntryPointsInstance[i] = GetProcAddressARB(new IntPtr(name + _EntryPointNameOffsetsInstance[i]));
}
}
}
IntPtr pointer = Arb.GetProcAddress("glXCreateContextAttribsARB");
IntPtr pointer = GetProcAddressARB("glXCreateContextAttribsARB");
if (pointer != null && pointer != IntPtr.Zero)
{
Arb.glXCreateContextAttribsARB = (Arb.CreateContextAttribsARB)Marshal.GetDelegateForFunctionPointer(
pointer, typeof(Arb.CreateContextAttribsARB));
pglXCreateContextAttribsARB = (glXCreateContextAttribsARB)Marshal.GetDelegateForFunctionPointer(
pointer, typeof(glXCreateContextAttribsARB));
}
glXSwapIntervalEXT = GetProcAddress<SwapIntervalEXT>("glXSwapIntervalEXT");
glXSwapIntervalMESA = GetProcAddress<SwapIntervalMESA>("glXSwapIntervalMESA");
glXGetSwapIntervalMESA = GetProcAddress<GetSwapIntervalMESA>("glXGetSwapIntervalMESA");
glXSwapIntervalSGI = GetProcAddress<SwapIntervalSGI>("glXSwapIntervalSGI");
}
public partial class Arb
{
[DllImport(Library, EntryPoint = "glXGetProcAddressARB")]
public static extern IntPtr GetProcAddress([MarshalAs(UnmanagedType.LPTStr)] string procName);
[DllImport(Library, EntryPoint = "glXGetProcAddressARB")]
public static extern IntPtr GetProcAddressARB([MarshalAs(UnmanagedType.LPTStr)] string procName);
[DllImport(Library, EntryPoint = "glXGetProcAddressARB")]
public static extern IntPtr GetProcAddress(IntPtr procName);
[DllImport(Library, EntryPoint = "glXGetProcAddressARB")]
public static extern IntPtr GetProcAddressARB(IntPtr procName);
public unsafe delegate IntPtr CreateContextAttribsARB(IntPtr display, IntPtr fbconfig, IntPtr share_context, bool direct, int* attribs);
public static unsafe CreateContextAttribsARB glXCreateContextAttribsARB = null;
}
internal delegate IntPtr glXCreateContextAttribsARB(IntPtr dpy, IntPtr config, IntPtr share_context, bool direct, int* attrib_list);
internal static glXCreateContextAttribsARB pglXCreateContextAttribsARB;
public delegate void SwapIntervalEXT(IntPtr dpy, IntPtr drawable, int interval);
public static SwapIntervalEXT glXSwapIntervalEXT;
public delegate int SwapIntervalMESA(uint interval);
public static SwapIntervalMESA glXSwapIntervalMESA;
public delegate int GetSwapIntervalMESA();
public static GetSwapIntervalMESA glXGetSwapIntervalMESA;
public delegate int SwapIntervalSGI(int interval);
public static SwapIntervalSGI glXSwapIntervalSGI;
internal static bool SupportsFunction(string name)
{
@ -423,6 +437,12 @@ namespace OpenTK.Platform.X11
}
}
}
public static TDelegate GetProcAddress<TDelegate>(string name) where TDelegate : class
{
IntPtr addr = GetProcAddress(name);
if (addr == IntPtr.Zero) return null;
return (TDelegate)(object)System.Runtime.InteropServices.Marshal.GetDelegateForFunctionPointer(addr, typeof(TDelegate));
}
// Returns an array of GLXFBConfig structures.
[DllImport(Library, EntryPoint = "glXChooseFBConfig")]
@ -431,22 +451,6 @@ namespace OpenTK.Platform.X11
// Returns a pointer to an XVisualInfo structure.
[DllImport(Library, EntryPoint = "glXGetVisualFromFBConfig")]
public unsafe extern static IntPtr GetVisualFromFBConfig(IntPtr dpy, IntPtr fbconfig);
[Slot(0)]
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
internal unsafe static extern IntPtr glXCreateContextAttribsARB(IntPtr display, IntPtr fbconfig, IntPtr share_context, bool direct, int* attribs);
[Slot(1)]
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
internal static extern ErrorCode glXSwapIntervalEXT(IntPtr display, IntPtr drawable, int interval);
[Slot(2)]
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
internal static extern ErrorCode glXSwapIntervalMESA(int interval);
[Slot(3)]
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
internal static extern int glXGetSwapIntervalMESA();
[Slot(4)]
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
internal static extern ErrorCode glXSwapIntervalSGI(int interval);
}
}

View file

@ -186,11 +186,11 @@ namespace OpenTK.Platform.X11
{
fixed (int* attribs_ptr = attributes.ToArray())
{
context = Glx.Arb.glXCreateContextAttribsARB(display, fbconfig, shareContext.Handle, direct, attribs_ptr);
context = Glx.pglXCreateContextAttribsARB(display, fbconfig, shareContext.Handle, direct, attribs_ptr);
if (context == IntPtr.Zero)
{
Debug.Write(String.Format("failed. Trying direct: {0}... ", !direct));
context = Glx.Arb.glXCreateContextAttribsARB(display, fbconfig, shareContext.Handle, !direct, attribs_ptr);
context = Glx.pglXCreateContextAttribsARB(display, fbconfig, shareContext.Handle, !direct, attribs_ptr);
}
}
}
@ -390,7 +390,7 @@ namespace OpenTK.Platform.X11
}
else if (vsync_mesa_supported)
{
return OpenGL.Glx.GetSwapIntervalMESA();
return Glx.glXGetSwapIntervalMESA();
}
else if (vsync_sgi_supported)
{
@ -418,15 +418,15 @@ namespace OpenTK.Platform.X11
{
if (vsync_ext_supported)
{
OpenGL.Glx.SwapIntervalEXT(Display, currentWindow.Handle, value);
Glx.glXSwapIntervalEXT(Display, currentWindow.Handle, value);
}
else if (vsync_mesa_supported)
{
error_code = (ErrorCode)OpenGL.Glx.SwapIntervalMESA((uint)value);
error_code = (ErrorCode)Glx.glXSwapIntervalMESA((uint)value);
}
else if (vsync_sgi_supported)
{
error_code = (ErrorCode)OpenGL.Glx.SwapIntervalSGI(value);
error_code = (ErrorCode)Glx.glXSwapIntervalMESA((uint)value);
}
}
@ -462,7 +462,7 @@ namespace OpenTK.Platform.X11
Debug.Print("Context supports adaptive vsync: {0}.",
vsync_tear_supported);
base.LoadAll();
GTKBindingHelper.InitializeGlBindings();
}
public override IntPtr GetAddress(IntPtr function)

View file

@ -10,7 +10,7 @@ namespace GLWidgetTestGTK3
{
public static void Main(string[] args)
{
GTKBindingHelper.InitXThreads();
// GTKBindingHelper.InitXThreads();
// GTK
Application.Init();
MainWindow win = MainWindow.Create();