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

View file

@ -41,39 +41,8 @@ namespace OpenTK.Platform
Stopwatch time = Stopwatch.StartNew(); Stopwatch time = Stopwatch.StartNew();
Assembly assembly; GTKBindingHelper.InitializeGlBindings();
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");
Debug.Print("Bindings loaded in {0} ms.", time.Elapsed.TotalMilliseconds); Debug.Print("Bindings loaded in {0} ms.", time.Elapsed.TotalMilliseconds);
} }
} }

View file

@ -253,7 +253,7 @@ namespace OpenTK.Platform.X11
/// <summary> /// <summary>
/// Provides access to GLX functions. /// Provides access to GLX functions.
/// </summary> /// </summary>
internal class Glx : Graphics.GraphicsBindingsBase internal unsafe class Glx : Graphics.GraphicsBindingsBase
{ {
private const string Library = "libGL.so.1"; private const string Library = "libGL.so.1";
private static readonly object sync_root = new object(); private static readonly object sync_root = new object();
@ -314,31 +314,45 @@ namespace OpenTK.Platform.X11
{ {
for (int i = 0; i < _EntryPointsInstance.Length; i++) 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) if (pointer != null && pointer != IntPtr.Zero)
{ {
Arb.glXCreateContextAttribsARB = (Arb.CreateContextAttribsARB)Marshal.GetDelegateForFunctionPointer( pglXCreateContextAttribsARB = (glXCreateContextAttribsARB)Marshal.GetDelegateForFunctionPointer(
pointer, typeof(Arb.CreateContextAttribsARB)); 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 GetProcAddressARB([MarshalAs(UnmanagedType.LPTStr)] string procName);
[DllImport(Library, EntryPoint = "glXGetProcAddressARB")]
public static extern IntPtr GetProcAddress([MarshalAs(UnmanagedType.LPTStr)] string procName);
[DllImport(Library, EntryPoint = "glXGetProcAddressARB")] [DllImport(Library, EntryPoint = "glXGetProcAddressARB")]
public static extern IntPtr GetProcAddress(IntPtr procName); public static extern IntPtr GetProcAddressARB(IntPtr procName);
public unsafe delegate IntPtr CreateContextAttribsARB(IntPtr display, IntPtr fbconfig, IntPtr share_context, bool direct, int* attribs); internal delegate IntPtr glXCreateContextAttribsARB(IntPtr dpy, IntPtr config, IntPtr share_context, bool direct, int* attrib_list);
public static unsafe CreateContextAttribsARB glXCreateContextAttribsARB = null; 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) 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. // Returns an array of GLXFBConfig structures.
[DllImport(Library, EntryPoint = "glXChooseFBConfig")] [DllImport(Library, EntryPoint = "glXChooseFBConfig")]
@ -430,23 +450,7 @@ namespace OpenTK.Platform.X11
// Returns a pointer to an XVisualInfo structure. // Returns a pointer to an XVisualInfo structure.
[DllImport(Library, EntryPoint = "glXGetVisualFromFBConfig")] [DllImport(Library, EntryPoint = "glXGetVisualFromFBConfig")]
public unsafe extern static IntPtr GetVisualFromFBConfig(IntPtr dpy, IntPtr fbconfig); 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()) 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) if (context == IntPtr.Zero)
{ {
Debug.Write(String.Format("failed. Trying direct: {0}... ", !direct)); 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) else if (vsync_mesa_supported)
{ {
return OpenGL.Glx.GetSwapIntervalMESA(); return Glx.glXGetSwapIntervalMESA();
} }
else if (vsync_sgi_supported) else if (vsync_sgi_supported)
{ {
@ -418,15 +418,15 @@ namespace OpenTK.Platform.X11
{ {
if (vsync_ext_supported) if (vsync_ext_supported)
{ {
OpenGL.Glx.SwapIntervalEXT(Display, currentWindow.Handle, value); Glx.glXSwapIntervalEXT(Display, currentWindow.Handle, value);
} }
else if (vsync_mesa_supported) 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) 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}.", Debug.Print("Context supports adaptive vsync: {0}.",
vsync_tear_supported); vsync_tear_supported);
base.LoadAll(); GTKBindingHelper.InitializeGlBindings();
} }
public override IntPtr GetAddress(IntPtr function) public override IntPtr GetAddress(IntPtr function)

View file

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