glxcontexts

This commit is contained in:
Emmanuel 2020-09-04 16:15:21 +00:00
parent 6fed327bc6
commit e59894411d
3 changed files with 211 additions and 20 deletions

View file

@ -55,11 +55,13 @@ namespace OpenTK
public bool HandleRendering { get; set; } = false;
#endregion
public IGraphicsContext NativeGraphicsContext { get; private set; }
#region Attributes
#endregion
private bool _initialized;
#region Attributes
private bool _initialized;
#endregion
@ -184,13 +186,13 @@ namespace OpenTK
OnRenderFrame();
}
cr.SetSourceColor(new Color(0, 0, 0, 1));
/*cr.SetSourceColor(new Color(0, 0, 0, 1));
cr.Paint();
var scale = this.ScaleFactor;
Gdk.CairoHelper.DrawFromGl(cr, this.Window, _renderbuffer, (int)ObjectLabelIdentifier.Renderbuffer, scale, 0, 0, AllocatedWidth, AllocatedHeight);
*/
return true;
}
@ -198,11 +200,13 @@ namespace OpenTK
{
GL.Flush();
QueueDraw();
//QueueDraw();
RecreateFramebuffer();
OpenTK.GraphicsContext.GetCurrentContext(Window.Handle).SwapBuffers();
if (HandleRendering)
//RecreateFramebuffer();
if (!HandleRendering)
{
ClearCurrent();
}
@ -210,8 +214,9 @@ namespace OpenTK
public void MakeCurrent()
{
GraphicsContext?.MakeCurrent();
GL.BindFramebuffer(FramebufferTarget.Framebuffer, _framebuffer);
ClearCurrent();
NativeGraphicsContext?.MakeCurrent();
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
}
public void ClearCurrent()
@ -292,12 +297,16 @@ namespace OpenTK
GraphicsContext.MakeCurrent();
if (!GTKBindingContext.Loaded)
if (!GTKBindingHelper.Loaded)
{
GTKBindingContext.InitializeGlBindings();
GTKBindingHelper.InitializeGlBindings();
}
CreateFramebuffer();
OpenTK.GraphicsContext.Display = this.Display.Handle;
NativeGraphicsContext = OpenTK.GraphicsContext.GetCurrentContext(this.Window.Handle);
// CreateFramebuffer();
OnInitialized();

View file

@ -1,4 +1,4 @@
using System;
using System;
using OpenTK;
using System.Runtime.InteropServices;
using System.Collections.Generic;
@ -6,8 +6,29 @@ using System.Reflection;
namespace OpenTK
{
public class GTKBindingContext : IBindingsContext
public class GTKBindingHelper : IBindingsContext
{
public static OSPlatform CurrentPlatform
{
get
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return OSPlatform.Windows;
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
return OSPlatform.Linux;
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
return OSPlatform.OSX;
}
return OSPlatform.Create("None");
}
}
public static bool Loaded;
private const string GlxLibrary = "libGL.so.1";
@ -24,7 +45,7 @@ namespace OpenTK
public IntPtr GetProcAddress(string procName)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
if (CurrentPlatform == OSPlatform.Windows)
{
var addr = GetProcAddressWgl(procName);
if (addr == null || addr == IntPtr.Zero)
@ -40,11 +61,11 @@ namespace OpenTK
}
return addr;
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
else if (CurrentPlatform == OSPlatform.Linux)
{
return GetProcAddressGlx(procName);
}
else if(RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
else if(CurrentPlatform == OSPlatform.OSX)
{
var osxAddr = !IsGlxRequired ? GetProcAddressOSX(procName) : GetProcAddressGlx(procName);
if (osxAddr != IntPtr.Zero)
@ -78,7 +99,7 @@ namespace OpenTK
return;
}
var provider = new GTKBindingContext();
var provider = new GTKBindingHelper();
void LoadBindings(string typeNamespace)
{
@ -165,7 +186,7 @@ namespace OpenTK
return symbol;
}
private static class UnsafeNativeMethods
internal static class UnsafeNativeMethods
{
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern IntPtr GetProcAddress(IntPtr handle, string funcname);
@ -179,6 +200,18 @@ namespace OpenTK
[DllImport(WglLibrary, EntryPoint = "wglGetProcAddress", ExactSpelling = true, SetLastError = true)]
public static extern IntPtr wglGetProcAddress(string lpszProc);
[DllImport(WglLibrary, EntryPoint = "wglGetCurrentContext")]
public extern static IntPtr wglGetCurrentContext();
[DllImport(WglLibrary, EntryPoint = "wglGetCurrentDC")]
public static extern IntPtr wglGetCurrentDC();
[DllImport(WglLibrary, EntryPoint = "wglSwapBuffers", ExactSpelling = true)]
public static extern bool wglSwapBuffers(IntPtr hdc);
[DllImport("opengl32.dll", SetLastError = true, EntryPoint = "wglMakeCurrent")]
public static extern bool WglMakeCurrent(IntPtr hdc, IntPtr hglrc);
[DllImport(OSXLibrary, EntryPoint = "NSIsSymbolNameDefined")]
public static extern bool NSIsSymbolNameDefined(string s);
@ -188,6 +221,15 @@ namespace OpenTK
[DllImport(OSXLibrary, EntryPoint = "NSAddressOfSymbol")]
public static extern IntPtr NSAddressOfSymbol(IntPtr symbol);
[DllImport(GlxLibrary, EntryPoint = "glXGetCurrentContext")]
public static extern IntPtr glXGetCurrentContext();
[DllImport(GlxLibrary, EntryPoint = "glXMakeCurrent")]
public static extern bool glXMakeCurrent(IntPtr display, IntPtr drawable, IntPtr context);
[DllImport(GlxLibrary, EntryPoint = "glXSwapBuffers")]
public static extern void glXSwapBuffers(IntPtr display, IntPtr drawable);
public const int RTLD_LAZY = 1;
public const int RTLD_NOW = 2;
@ -200,6 +242,26 @@ namespace OpenTK
[DllImport("dl")]
public static extern string dlerror();
public const string GdkNativeDll = "libgdk-3-0.dll";
[DllImport(GdkNativeDll, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr gdk_win32_drawable_get_handle(IntPtr raw);
[DllImport(GdkNativeDll, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr gdk_win32_hdc_get(IntPtr drawable, IntPtr gc, int usage);
[DllImport(GdkNativeDll, CallingConvention = CallingConvention.Cdecl)]
public static extern void gdk_win32_hdc_release(IntPtr drawable, IntPtr gc, int usage);
[DllImport("libgdk-3.so.0", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr gdk_x11_display_get_xdisplay(IntPtr raw);
[DllImport("libgdk-3.so.0", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr gdk_x11_window_get_xid(IntPtr raw);
[DllImport(GdkNativeDll, CallingConvention = CallingConvention.Cdecl)]
public static extern void gdk_window_get_internal_paint_info(IntPtr raw, out IntPtr real_drawable, out int x, out int y);
}
private static class Delegates

120
GLWidget/GraphicsContext.cs Normal file
View file

@ -0,0 +1,120 @@
using System;
using System.Runtime.InteropServices;
using static OpenTK.GTKBindingHelper;
namespace OpenTK
{
public interface IGraphicsContext
{
void MakeCurrent();
void SwapBuffers();
void ClearCurrent();
}
public abstract class GraphicsContext : IGraphicsContext
{
public static IntPtr Display{ get; set; }
public abstract void MakeCurrent();
public abstract void SwapBuffers();
public static IGraphicsContext GetCurrentContext(IntPtr handle)
{
var currentPlatform = CurrentPlatform;
if(currentPlatform == OSPlatform.Windows){
return WglGraphicsContext.GetCurrent(handle);
}
else if(currentPlatform == OSPlatform.Linux){
if (Display == null || Display == IntPtr.Zero)
{
throw new InvalidOperationException("No Display set");
}
return GlxGraphicsContext.GetCurrent(handle, Display);
}
return null;
}
public abstract void ClearCurrent();
}
public class WglGraphicsContext : GraphicsContext
{
private IntPtr _windowHandle;
private IntPtr _deviceContext;
public WglGraphicsContext(IntPtr deviceContext, IntPtr graphicsContext, IntPtr windowHandle = default)
{
_deviceContext = deviceContext;
_graphicsContext = graphicsContext;
_windowHandle = windowHandle;
}
private IntPtr _graphicsContext;
public static WglGraphicsContext GetCurrent(IntPtr windowHandle)
{
IntPtr dc = UnsafeNativeMethods.wglGetCurrentDC();
IntPtr gc = UnsafeNativeMethods.wglGetCurrentContext();
return new WglGraphicsContext(dc, gc, windowHandle);
}
public override void MakeCurrent()
{
UnsafeNativeMethods.WglMakeCurrent(_deviceContext, _graphicsContext);
}
public override void SwapBuffers()
{
UnsafeNativeMethods.wglSwapBuffers(_deviceContext);
}
public override void ClearCurrent()
{
throw new NotImplementedException();
}
}
public class GlxGraphicsContext : GraphicsContext
{
private IntPtr _windowHandle;
private IntPtr _drawable;
public static GlxGraphicsContext GetCurrent(IntPtr windowHandle, IntPtr display)
{
var gc = UnsafeNativeMethods.glXGetCurrentContext();
return new GlxGraphicsContext(windowHandle, gc, display);
}
public GlxGraphicsContext(IntPtr windowHandle, IntPtr graphicsContext, IntPtr display)
{
_windowHandle = UnsafeNativeMethods.gdk_x11_window_get_xid(windowHandle);
_display = UnsafeNativeMethods.gdk_x11_display_get_xdisplay(display);
_graphicsContext = graphicsContext;
}
private IntPtr _graphicsContext;
private IntPtr _display;
public override void MakeCurrent()
{
UnsafeNativeMethods.glXMakeCurrent(_display, _windowHandle, _graphicsContext);
}
public override void SwapBuffers()
{
UnsafeNativeMethods.glXSwapBuffers(_display, _windowHandle);
}
public override void ClearCurrent()
{
UnsafeNativeMethods.glXMakeCurrent(_display, _windowHandle, IntPtr.Zero);
}
}
}