mirror of
https://github.com/Ryujinx/GLWidget.git
synced 2025-01-03 16:15:35 +00:00
update to opentk4
This commit is contained in:
parent
e59894411d
commit
d573036187
|
@ -41,22 +41,118 @@ using OpenTK.Graphics.OpenGL;
|
||||||
using Gtk;
|
using Gtk;
|
||||||
using Cairo;
|
using Cairo;
|
||||||
using GLib;
|
using GLib;
|
||||||
|
using Gdk;
|
||||||
|
using OpenGL;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using OpenTK.Mathematics;
|
||||||
|
|
||||||
namespace OpenTK
|
namespace OpenTK
|
||||||
{
|
{
|
||||||
[ToolboxItem(true)]
|
[ToolboxItem(true)]
|
||||||
public class GLWidget : DrawingArea
|
public class GLWidget : DrawingArea
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Get or set the OpenGL minimum color buffer bits.
|
||||||
|
/// </summary>
|
||||||
|
[Property("color-bits")]
|
||||||
|
public uint ColorBits
|
||||||
|
{
|
||||||
|
get { return (_ColorBits); }
|
||||||
|
set { _ColorBits = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The OpenGL color buffer bits.
|
||||||
|
/// </summary>
|
||||||
|
private uint _ColorBits = 24;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get or set the OpenGL minimum depth buffer bits.
|
||||||
|
/// </summary>
|
||||||
|
[Property("depth-bits")]
|
||||||
|
public uint DepthBits
|
||||||
|
{
|
||||||
|
get { return (_DepthBits); }
|
||||||
|
set { _DepthBits = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The OpenGL color buffer bits.
|
||||||
|
/// </summary>
|
||||||
|
private uint _DepthBits;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get or set the OpenGL minimum stencil buffer bits.
|
||||||
|
/// </summary>
|
||||||
|
[Property("stencil-bits")]
|
||||||
|
public uint StencilBits
|
||||||
|
{
|
||||||
|
get { return (_StencilBits); }
|
||||||
|
set { _StencilBits = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The OpenGL color buffer bits.
|
||||||
|
/// </summary>
|
||||||
|
private uint _StencilBits;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get or set the OpenGL minimum multisample buffer "bits".
|
||||||
|
/// </summary>
|
||||||
|
[Property("multisample-bits")]
|
||||||
|
public uint MultisampleBits
|
||||||
|
{
|
||||||
|
get { return (_MultisampleBits); }
|
||||||
|
set { _MultisampleBits = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The OpenGL multisample buffer bits.
|
||||||
|
/// </summary>
|
||||||
|
private uint _MultisampleBits;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get or set the OpenGL swap buffers interval.
|
||||||
|
/// </summary>
|
||||||
|
[Property("swap-interval")]
|
||||||
|
public int SwapInterval
|
||||||
|
{
|
||||||
|
get { return (_SwapInterval); }
|
||||||
|
set { _SwapInterval = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The OpenGL swap buffers interval.
|
||||||
|
/// </summary>
|
||||||
|
private int _SwapInterval = 1;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="DevicePixelFormat"/> describing the minimum pixel format required by this control.
|
||||||
|
/// </summary>
|
||||||
|
private DevicePixelFormat ControlPixelFormat
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
DevicePixelFormat controlReqFormat = new DevicePixelFormat();
|
||||||
|
|
||||||
|
controlReqFormat.RgbaUnsigned = true;
|
||||||
|
controlReqFormat.RenderWindow = true;
|
||||||
|
|
||||||
|
controlReqFormat.ColorBits = (int)ColorBits;
|
||||||
|
controlReqFormat.DepthBits = (int)DepthBits;
|
||||||
|
controlReqFormat.StencilBits = (int)StencilBits;
|
||||||
|
controlReqFormat.MultisampleBits = (int)MultisampleBits;
|
||||||
|
controlReqFormat.DoubleBuffer = true;
|
||||||
|
|
||||||
|
return (controlReqFormat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#region Static attrs.
|
#region Static attrs.
|
||||||
|
|
||||||
private static int _graphicsContextCount;
|
|
||||||
private static bool _sharedContextInitialized;
|
|
||||||
|
|
||||||
public bool HandleRendering { get; set; } = false;
|
public bool HandleRendering { get; set; } = false;
|
||||||
|
|
||||||
public IGraphicsContext NativeGraphicsContext { get; private set; }
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Attributes
|
#region Attributes
|
||||||
|
@ -73,13 +169,14 @@ 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; }
|
||||||
|
|
||||||
private int _framebuffer;
|
private DeviceContext _deviceContext;
|
||||||
private int _renderbuffer;
|
private IntPtr _graphicsContext;
|
||||||
private int _stencilbuffer;
|
private int _error;
|
||||||
private bool _recreateFramebuffer;
|
|
||||||
|
private IGraphicsContext _context;
|
||||||
|
|
||||||
public Gdk.GLContext GraphicsContext { get; set; }
|
|
||||||
public bool ForwardCompatible { get; }
|
public bool ForwardCompatible { get; }
|
||||||
|
public DeviceContext DeviceContext { get => _deviceContext; set => _deviceContext = value; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -88,7 +185,9 @@ namespace OpenTK
|
||||||
/// <summary>Constructs a new GLWidget</summary>
|
/// <summary>Constructs a new GLWidget</summary>
|
||||||
public GLWidget() : this(new Version(4, 0), true)
|
public GLWidget() : this(new Version(4, 0), true)
|
||||||
{
|
{
|
||||||
|
/*this.ColorBits = 32;
|
||||||
|
this.DepthBits = 24;
|
||||||
|
this.StencilBits = 8;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Constructs a new GLWidget</summary>
|
/// <summary>Constructs a new GLWidget</summary>
|
||||||
|
@ -110,7 +209,9 @@ namespace OpenTK
|
||||||
{
|
{
|
||||||
OnShuttingDown();
|
OnShuttingDown();
|
||||||
|
|
||||||
GraphicsContext.Dispose();
|
DeviceContext.DeleteContext(_graphicsContext);
|
||||||
|
|
||||||
|
DeviceContext.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,25 +222,9 @@ namespace OpenTK
|
||||||
// Called when the first GraphicsContext is created in the case of GraphicsContext.ShareContexts == True;
|
// Called when the first GraphicsContext is created in the case of GraphicsContext.ShareContexts == True;
|
||||||
public static event EventHandler GraphicsContextInitialized;
|
public static event EventHandler GraphicsContextInitialized;
|
||||||
|
|
||||||
private static void OnGraphicsContextInitialized()
|
|
||||||
{
|
|
||||||
if (GraphicsContextInitialized != null)
|
|
||||||
{
|
|
||||||
GraphicsContextInitialized(null, EventArgs.Empty);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called when the first GraphicsContext is being destroyed in the case of GraphicsContext.ShareContexts == True;
|
// Called when the first GraphicsContext is being destroyed in the case of GraphicsContext.ShareContexts == True;
|
||||||
public static event EventHandler GraphicsContextShuttingDown;
|
public static event EventHandler GraphicsContextShuttingDown;
|
||||||
|
|
||||||
private static void OnGraphicsContextShuttingDown()
|
|
||||||
{
|
|
||||||
if (GraphicsContextShuttingDown != null)
|
|
||||||
{
|
|
||||||
GraphicsContextShuttingDown(null, EventArgs.Empty);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called when this GLWidget has a valid GraphicsContext
|
// Called when this GLWidget has a valid GraphicsContext
|
||||||
public event EventHandler Initialized;
|
public event EventHandler Initialized;
|
||||||
|
|
||||||
|
@ -177,140 +262,177 @@ namespace OpenTK
|
||||||
protected override bool OnDrawn(Cairo.Context cr)
|
protected override bool OnDrawn(Cairo.Context cr)
|
||||||
{
|
{
|
||||||
if (!_initialized)
|
if (!_initialized)
|
||||||
System.Threading.Tasks.Task.Run(Initialize).Wait();
|
Initialize();
|
||||||
|
|
||||||
if (HandleRendering)
|
ClearCurrent();
|
||||||
{
|
|
||||||
MakeCurrent();
|
|
||||||
|
|
||||||
OnRenderFrame();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Swapbuffers()
|
public void Swapbuffers()
|
||||||
{
|
{
|
||||||
GL.Flush();
|
DeviceContext?.SwapBuffers();
|
||||||
|
|
||||||
//QueueDraw();
|
|
||||||
|
|
||||||
OpenTK.GraphicsContext.GetCurrentContext(Window.Handle).SwapBuffers();
|
|
||||||
|
|
||||||
//RecreateFramebuffer();
|
|
||||||
|
|
||||||
if (!HandleRendering)
|
|
||||||
{
|
|
||||||
ClearCurrent();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void MakeCurrent()
|
public void MakeCurrent()
|
||||||
{
|
{
|
||||||
ClearCurrent();
|
ClearCurrent();
|
||||||
NativeGraphicsContext?.MakeCurrent();
|
|
||||||
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
|
_context?.MakeCurrent();
|
||||||
|
|
||||||
|
_error = Marshal.GetLastWin32Error();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClearCurrent()
|
public void ClearCurrent()
|
||||||
{
|
{
|
||||||
Gdk.GLContext.ClearCurrent();
|
//Gdk.GLContext.ClearCurrent();
|
||||||
|
DeviceContext?.MakeCurrent(IntPtr.Zero);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called on Resize
|
private void CreateContext()
|
||||||
protected override bool OnConfigureEvent(Gdk.EventConfigure evnt)
|
|
||||||
{
|
{
|
||||||
if (GraphicsContext != null)
|
if (_graphicsContext != IntPtr.Zero)
|
||||||
|
throw new InvalidOperationException("context already created");
|
||||||
|
|
||||||
|
IntPtr sharingContext = IntPtr.Zero;
|
||||||
|
|
||||||
|
if (Gl.PlatformExtensions.CreateContext_ARB)
|
||||||
{
|
{
|
||||||
_recreateFramebuffer = true;
|
List<int> attributes = new List<int>();
|
||||||
|
uint contextProfile = 0, contextFlags = 0;
|
||||||
|
bool debuggerAttached = Debugger.IsAttached;
|
||||||
|
|
||||||
|
#region WGL_ARB_create_context|GLX_ARB_create_context
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region WGL_ARB_create_context_profile|GLX_ARB_create_context_profile
|
||||||
|
|
||||||
|
if (Gl.PlatformExtensions.CreateContextProfile_ARB)
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
#endregion
|
||||||
|
|
||||||
|
#region WGL_ARB_create_context_robustness|GLX_ARB_create_context_robustness
|
||||||
|
|
||||||
|
if (Gl.PlatformExtensions.CreateContextRobustness_ARB)
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RecreateFramebuffer()
|
#endregion
|
||||||
{
|
|
||||||
if (!_recreateFramebuffer)
|
Debug.Assert(Wgl.CONTEXT_FLAGS_ARB == Glx.CONTEXT_FLAGS_ARB);
|
||||||
{
|
if (contextFlags != 0)
|
||||||
return;
|
attributes.AddRange(new int[] { Wgl.CONTEXT_FLAGS_ARB, unchecked((int)contextFlags) });
|
||||||
|
|
||||||
|
Debug.Assert(Wgl.CONTEXT_PROFILE_MASK_ARB == Glx.CONTEXT_PROFILE_MASK_ARB);
|
||||||
|
Debug.Assert(contextProfile == 0 || Gl.PlatformExtensions.CreateContextProfile_ARB);
|
||||||
|
if (contextProfile != 0)
|
||||||
|
attributes.AddRange(new int[] { Wgl.CONTEXT_PROFILE_MASK_ARB, unchecked((int)contextProfile) });
|
||||||
|
|
||||||
|
attributes.Add(0);
|
||||||
|
|
||||||
|
if ((_graphicsContext = _deviceContext.CreateContextAttrib(sharingContext, attributes.ToArray())) == IntPtr.Zero)
|
||||||
|
throw new InvalidOperationException(String.Format("unable to create render context ({0})", Gl.GetError()));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
_recreateFramebuffer = false;
|
|
||||||
|
|
||||||
GraphicsContext.Window.Resize(AllocatedWidth, AllocatedHeight);
|
|
||||||
|
|
||||||
DeleteBuffers();
|
|
||||||
|
|
||||||
CreateFramebuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DeleteBuffers()
|
|
||||||
{
|
{
|
||||||
if (_framebuffer != 0)
|
// Create OpenGL context using compatibility profile
|
||||||
{
|
if ((_graphicsContext = _deviceContext.CreateContext(sharingContext)) == IntPtr.Zero)
|
||||||
GL.DeleteFramebuffer(_framebuffer);
|
throw new InvalidOperationException("unable to create render context");
|
||||||
GL.DeleteRenderbuffer(_renderbuffer);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateFramebuffer()
|
private void CreateDeviceContext(DevicePixelFormat controlReqFormat)
|
||||||
{
|
{
|
||||||
_framebuffer = GL.GenFramebuffer();
|
#region Create device context
|
||||||
GL.BindFramebuffer(FramebufferTarget.Framebuffer, _framebuffer);
|
|
||||||
|
|
||||||
_renderbuffer = GL.GenRenderbuffer();
|
DeviceContext = DeviceContext.Create(GTKBindingHelper.GetDisplayHandle(Display.Handle), GTKBindingHelper.GetWindowHandle(Window.Handle));
|
||||||
GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, _renderbuffer);
|
DeviceContext.IncRef();
|
||||||
GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, RenderbufferStorage.Rgba8, AllocatedWidth, AllocatedHeight);
|
|
||||||
|
|
||||||
GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, RenderbufferTarget.Renderbuffer, _renderbuffer);
|
#endregion
|
||||||
|
|
||||||
_stencilbuffer = GL.GenRenderbuffer();
|
#region Set pixel format
|
||||||
GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, _stencilbuffer);
|
|
||||||
GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, RenderbufferStorage.Depth24Stencil8, AllocatedWidth, AllocatedHeight);
|
|
||||||
|
|
||||||
GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthStencilAttachment, RenderbufferTarget.Renderbuffer, _stencilbuffer);
|
DevicePixelFormatCollection pixelFormats = DeviceContext.PixelsFormats;
|
||||||
|
List<DevicePixelFormat> matchingPixelFormats = pixelFormats.Choose(controlReqFormat);
|
||||||
|
|
||||||
GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, 0);
|
if ((matchingPixelFormats.Count == 0) && controlReqFormat.MultisampleBits > 0)
|
||||||
var state = GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer);
|
{
|
||||||
|
// Try to select the maximum multisample configuration
|
||||||
|
int multisampleBits = 0;
|
||||||
|
|
||||||
|
pixelFormats.ForEach(delegate (DevicePixelFormat item) { multisampleBits = Math.Max(multisampleBits, item.MultisampleBits); });
|
||||||
|
|
||||||
|
controlReqFormat.MultisampleBits = multisampleBits;
|
||||||
|
|
||||||
|
matchingPixelFormats = pixelFormats.Choose(controlReqFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((matchingPixelFormats.Count == 0) && controlReqFormat.DoubleBuffer)
|
||||||
|
{
|
||||||
|
// Try single buffered pixel formats
|
||||||
|
controlReqFormat.DoubleBuffer = false;
|
||||||
|
|
||||||
|
matchingPixelFormats = pixelFormats.Choose(controlReqFormat);
|
||||||
|
if (matchingPixelFormats.Count == 0)
|
||||||
|
throw new InvalidOperationException(String.Format("unable to find a suitable pixel format: {0}", pixelFormats.GuessChooseError(controlReqFormat)));
|
||||||
|
}
|
||||||
|
else if (matchingPixelFormats.Count == 0)
|
||||||
|
throw new InvalidOperationException(String.Format("unable to find a suitable pixel format: {0}", pixelFormats.GuessChooseError(controlReqFormat)));
|
||||||
|
|
||||||
|
DeviceContext.SetPixelFormat(matchingPixelFormats[0]);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Set V-Sync
|
||||||
|
|
||||||
|
if (Gl.PlatformExtensions.SwapControl)
|
||||||
|
{
|
||||||
|
int swapInterval = SwapInterval;
|
||||||
|
|
||||||
|
// Mask value in case it is not supported
|
||||||
|
if (!Gl.PlatformExtensions.SwapControlTear && swapInterval == -1)
|
||||||
|
swapInterval = 1;
|
||||||
|
|
||||||
|
DeviceContext.SwapInterval(swapInterval);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Initialize()
|
private void Initialize()
|
||||||
{
|
{
|
||||||
_initialized = true;
|
ClearCurrent();
|
||||||
|
|
||||||
GraphicsContext = Window.CreateGlContext();
|
Khronos.KhronosApi.LogEnabled = true;
|
||||||
|
Wgl.ErrorHandling = Wgl.ErrorHandlingMode.Normal;
|
||||||
|
|
||||||
GraphicsContext.SetRequiredVersion(GLVersionMajor, GLVersionMinor);
|
Window.EnsureNative();
|
||||||
|
|
||||||
GraphicsContext.SetUseEs(0);
|
CreateDeviceContext(ControlPixelFormat);
|
||||||
|
|
||||||
GraphicsContext.ForwardCompatible = ForwardCompatible;
|
CreateContext();
|
||||||
|
|
||||||
GraphicsContext.Realize();
|
DeviceContext.MakeCurrent(_graphicsContext);
|
||||||
|
|
||||||
GraphicsContext.MakeCurrent();
|
_context = GraphicsContext.GetCurrentContext(Window.Handle);
|
||||||
|
|
||||||
|
MakeCurrent();
|
||||||
|
|
||||||
if (!GTKBindingHelper.Loaded)
|
|
||||||
{
|
|
||||||
GTKBindingHelper.InitializeGlBindings();
|
GTKBindingHelper.InitializeGlBindings();
|
||||||
}
|
|
||||||
|
|
||||||
OpenTK.GraphicsContext.Display = this.Display.Handle;
|
|
||||||
|
|
||||||
NativeGraphicsContext = OpenTK.GraphicsContext.GetCurrentContext(this.Window.Handle);
|
|
||||||
|
|
||||||
// CreateFramebuffer();
|
|
||||||
|
|
||||||
OnInitialized();
|
OnInitialized();
|
||||||
|
|
||||||
|
OpenTK.GraphicsContext.GetCurrentContext(Window.Handle).SwapInterval(1);
|
||||||
|
|
||||||
ClearCurrent();
|
ClearCurrent();
|
||||||
|
|
||||||
|
_initialized = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,13 +1,14 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.1</TargetFramework>
|
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
<Description>GLWigdet for GTKSharp, using Opentk.</Description>
|
<Description>GLWigdet for GTKSharp, using Opentk.</Description>
|
||||||
<Version>1.0.1</Version>
|
<Version>1.0.3-pre1</Version>
|
||||||
<RepositoryUrl>https://github.com/Ryujinx/GLWidget</RepositoryUrl>
|
<RepositoryUrl>https://github.com/Ryujinx/GLWidget</RepositoryUrl>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="GtkSharp" Version="3.22.25.56" />
|
<PackageReference Include="GtkSharp" Version="3.22.25.56" />
|
||||||
|
<PackageReference Include="OpenGL.Net" Version="0.8.4" />
|
||||||
<PackageReference Include="OpenTK.Graphics" Version="4.0.0-pre9.4" />
|
<PackageReference Include="OpenTK.Graphics" Version="4.0.0-pre9.4" />
|
||||||
<PackageReference Include="OpenTK.Windowing.Common" Version="4.0.0-pre9.4" />
|
<PackageReference Include="OpenTK.Windowing.Common" Version="4.0.0-pre9.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -147,6 +147,30 @@ namespace OpenTK
|
||||||
Loaded = true;
|
Loaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IntPtr GetWindowHandle(IntPtr handle)
|
||||||
|
{
|
||||||
|
if(CurrentPlatform == OSPlatform.Windows)
|
||||||
|
{
|
||||||
|
return UnsafeNativeMethods.gdk_win32_window_get_handle(handle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return UnsafeNativeMethods.gdk_x11_window_get_xid(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IntPtr GetDisplayHandle(IntPtr handle)
|
||||||
|
{
|
||||||
|
if (CurrentPlatform == OSPlatform.Windows)
|
||||||
|
{
|
||||||
|
return IntPtr.Zero;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return UnsafeNativeMethods.gdk_x11_display_get_xdisplay(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal static IntPtr GetLibraryHandle(string libraryPath, bool throws)
|
internal static IntPtr GetLibraryHandle(string libraryPath, bool throws)
|
||||||
{
|
{
|
||||||
IntPtr libraryHandle;
|
IntPtr libraryHandle;
|
||||||
|
@ -191,9 +215,6 @@ namespace OpenTK
|
||||||
[DllImport("kernel32.dll", SetLastError = true)]
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
internal static extern IntPtr GetProcAddress(IntPtr handle, string funcname);
|
internal static extern IntPtr GetProcAddress(IntPtr handle, string funcname);
|
||||||
|
|
||||||
[DllImport("kernel32.dll", SetLastError = true)]
|
|
||||||
internal static extern IntPtr GetProcAddress(IntPtr handle, IntPtr funcname);
|
|
||||||
|
|
||||||
[DllImport("kernel32.dll", SetLastError = true)]
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
internal static extern IntPtr LoadLibrary(string dllName);
|
internal static extern IntPtr LoadLibrary(string dllName);
|
||||||
|
|
||||||
|
@ -224,6 +245,12 @@ namespace OpenTK
|
||||||
[DllImport(GlxLibrary, EntryPoint = "glXGetCurrentContext")]
|
[DllImport(GlxLibrary, EntryPoint = "glXGetCurrentContext")]
|
||||||
public static extern IntPtr glXGetCurrentContext();
|
public static extern IntPtr glXGetCurrentContext();
|
||||||
|
|
||||||
|
[DllImport(GlxLibrary, EntryPoint = "glXGetProcAddress")]
|
||||||
|
public static extern IntPtr glXGetProcAddress();
|
||||||
|
|
||||||
|
[DllImport(GlxLibrary, EntryPoint = "glXSwapIntervalEXT")]
|
||||||
|
public static extern IntPtr glXSwapIntervalEXT(int interval);
|
||||||
|
|
||||||
[DllImport(GlxLibrary, EntryPoint = "glXMakeCurrent")]
|
[DllImport(GlxLibrary, EntryPoint = "glXMakeCurrent")]
|
||||||
public static extern bool glXMakeCurrent(IntPtr display, IntPtr drawable, IntPtr context);
|
public static extern bool glXMakeCurrent(IntPtr display, IntPtr drawable, IntPtr context);
|
||||||
|
|
||||||
|
@ -246,22 +273,13 @@ namespace OpenTK
|
||||||
public const string GdkNativeDll = "libgdk-3-0.dll";
|
public const string GdkNativeDll = "libgdk-3-0.dll";
|
||||||
|
|
||||||
[DllImport(GdkNativeDll, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(GdkNativeDll, CallingConvention = CallingConvention.Cdecl)]
|
||||||
public static extern IntPtr gdk_win32_drawable_get_handle(IntPtr raw);
|
public static extern IntPtr gdk_win32_window_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)]
|
[DllImport("libgdk-3.so.0", CallingConvention = CallingConvention.Cdecl)]
|
||||||
public static extern IntPtr gdk_x11_display_get_xdisplay(IntPtr raw);
|
public static extern IntPtr gdk_x11_display_get_xdisplay(IntPtr raw);
|
||||||
|
|
||||||
[DllImport("libgdk-3.so.0", CallingConvention = CallingConvention.Cdecl)]
|
[DllImport("libgdk-3.so.0", CallingConvention = CallingConvention.Cdecl)]
|
||||||
public static extern IntPtr gdk_x11_window_get_xid(IntPtr raw);
|
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
|
private static class Delegates
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using OpenGL;
|
||||||
|
|
||||||
using static OpenTK.GTKBindingHelper;
|
using static OpenTK.GTKBindingHelper;
|
||||||
|
|
||||||
namespace OpenTK
|
namespace OpenTK
|
||||||
|
@ -8,8 +10,8 @@ namespace OpenTK
|
||||||
{
|
{
|
||||||
void MakeCurrent();
|
void MakeCurrent();
|
||||||
void SwapBuffers();
|
void SwapBuffers();
|
||||||
|
|
||||||
void ClearCurrent();
|
void ClearCurrent();
|
||||||
|
void SwapInterval(int interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class GraphicsContext : IGraphicsContext
|
public abstract class GraphicsContext : IGraphicsContext
|
||||||
|
@ -20,6 +22,24 @@ namespace OpenTK
|
||||||
|
|
||||||
public abstract void SwapBuffers();
|
public abstract void SwapBuffers();
|
||||||
|
|
||||||
|
public static void InitializeDefaults(IntPtr handle)
|
||||||
|
{
|
||||||
|
if (CurrentPlatform == OSPlatform.Windows)
|
||||||
|
{
|
||||||
|
IntPtr deviceContext = Wgl.GetDC(UnsafeNativeMethods.gdk_win32_window_get_handle(handle));
|
||||||
|
|
||||||
|
Wgl.PIXELFORMATDESCRIPTOR pfd = new Wgl.PIXELFORMATDESCRIPTOR(24);
|
||||||
|
|
||||||
|
pfd.dwFlags |= Wgl.PixelFormatDescriptorFlags.DepthDontCare | Wgl.PixelFormatDescriptorFlags.DoublebufferDontCare | Wgl.PixelFormatDescriptorFlags.StereoDontCare;
|
||||||
|
|
||||||
|
int pFormat = Wgl.ChoosePixelFormat(deviceContext, ref pfd);
|
||||||
|
|
||||||
|
bool res = Wgl.DescribePixelFormat(deviceContext, pFormat, (uint)pfd.nSize, ref pfd) != 0;
|
||||||
|
|
||||||
|
res = Wgl.SetPixelFormat(deviceContext, pFormat, ref pfd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static IGraphicsContext GetCurrentContext(IntPtr handle)
|
public static IGraphicsContext GetCurrentContext(IntPtr handle)
|
||||||
{
|
{
|
||||||
var currentPlatform = CurrentPlatform;
|
var currentPlatform = CurrentPlatform;
|
||||||
|
@ -39,10 +59,14 @@ namespace OpenTK
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void ClearCurrent();
|
public abstract void ClearCurrent();
|
||||||
|
public abstract void SwapInterval(int interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class WglGraphicsContext : GraphicsContext
|
public class WglGraphicsContext : GraphicsContext
|
||||||
{
|
{
|
||||||
|
private delegate int wglSwapIntervalExtDelegate(int interval);
|
||||||
|
private static wglSwapIntervalExtDelegate wglSwapIntervalExt = null;
|
||||||
|
|
||||||
private IntPtr _windowHandle;
|
private IntPtr _windowHandle;
|
||||||
private IntPtr _deviceContext;
|
private IntPtr _deviceContext;
|
||||||
|
|
||||||
|
@ -51,6 +75,14 @@ namespace OpenTK
|
||||||
_deviceContext = deviceContext;
|
_deviceContext = deviceContext;
|
||||||
_graphicsContext = graphicsContext;
|
_graphicsContext = graphicsContext;
|
||||||
_windowHandle = windowHandle;
|
_windowHandle = windowHandle;
|
||||||
|
|
||||||
|
IntPtr swapIntervalPointer = UnsafeNativeMethods.wglGetProcAddress("wglSwapIntervalEXT");
|
||||||
|
|
||||||
|
if(swapIntervalPointer != null && swapIntervalPointer != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
wglSwapIntervalExt = (wglSwapIntervalExtDelegate)Marshal.GetDelegateForFunctionPointer(
|
||||||
|
swapIntervalPointer, typeof(wglSwapIntervalExtDelegate));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IntPtr _graphicsContext;
|
private IntPtr _graphicsContext;
|
||||||
|
@ -75,7 +107,12 @@ namespace OpenTK
|
||||||
|
|
||||||
public override void ClearCurrent()
|
public override void ClearCurrent()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
UnsafeNativeMethods.WglMakeCurrent(_deviceContext, IntPtr.Zero);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SwapInterval(int interval)
|
||||||
|
{
|
||||||
|
wglSwapIntervalExt?.Invoke(interval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,8 +120,6 @@ namespace OpenTK
|
||||||
{
|
{
|
||||||
private IntPtr _windowHandle;
|
private IntPtr _windowHandle;
|
||||||
|
|
||||||
private IntPtr _drawable;
|
|
||||||
|
|
||||||
public static GlxGraphicsContext GetCurrent(IntPtr windowHandle, IntPtr display)
|
public static GlxGraphicsContext GetCurrent(IntPtr windowHandle, IntPtr display)
|
||||||
{
|
{
|
||||||
var gc = UnsafeNativeMethods.glXGetCurrentContext();
|
var gc = UnsafeNativeMethods.glXGetCurrentContext();
|
||||||
|
@ -116,5 +151,10 @@ namespace OpenTK
|
||||||
{
|
{
|
||||||
UnsafeNativeMethods.glXMakeCurrent(_display, _windowHandle, IntPtr.Zero);
|
UnsafeNativeMethods.glXMakeCurrent(_display, _windowHandle, IntPtr.Zero);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void SwapInterval(int interval)
|
||||||
|
{
|
||||||
|
UnsafeNativeMethods.glXSwapIntervalEXT(interval);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -342,7 +342,10 @@ namespace GLWidgetTestGTK3
|
||||||
|
|
||||||
// Add idle event handler to process rendering whenever and as long as time is available.
|
// Add idle event handler to process rendering whenever and as long as time is available.
|
||||||
GLInit = true;
|
GLInit = true;
|
||||||
GLib.Idle.Add(OnIdleProcessMain);
|
//GLib.Idle.Add(OnIdleProcessMain);
|
||||||
|
|
||||||
|
System.Threading.Thread thread = new System.Threading.Thread(Start);
|
||||||
|
thread.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void RenderFrame()
|
protected void RenderFrame()
|
||||||
|
@ -449,6 +452,20 @@ namespace GLWidgetTestGTK3
|
||||||
|
|
||||||
//swap
|
//swap
|
||||||
MainGLWidget.Swapbuffers();
|
MainGLWidget.Swapbuffers();
|
||||||
|
|
||||||
|
MainGLWidget.ClearCurrent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
System.Threading.Thread.Sleep(1000);
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
RenderFrame();
|
||||||
|
|
||||||
|
System.Threading.Thread.Sleep(5);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected bool OnIdleProcessMain()
|
protected bool OnIdleProcessMain()
|
||||||
|
@ -461,9 +478,9 @@ namespace GLWidgetTestGTK3
|
||||||
Stopwatch deltaTimeWatcher = new Stopwatch();
|
Stopwatch deltaTimeWatcher = new Stopwatch();
|
||||||
deltaTimeWatcher.Start();
|
deltaTimeWatcher.Start();
|
||||||
|
|
||||||
System.Threading.Tasks.Task.Run(RenderFrame).Wait();
|
//System.Threading.Tasks.Task.Run(RenderFrame).Wait();
|
||||||
|
|
||||||
//RenderFrame();
|
RenderFrame();
|
||||||
|
|
||||||
// End delta time calculation
|
// End delta time calculation
|
||||||
deltaTimeWatcher.Stop();
|
deltaTimeWatcher.Stop();
|
||||||
|
|
Loading…
Reference in a new issue