mirror of
https://github.com/Ryujinx/GLWidget.git
synced 2025-07-04 03:08:24 +00:00
160 lines
5.1 KiB
C#
160 lines
5.1 KiB
C#
using System;
|
|
using System.Runtime.InteropServices;
|
|
using OpenGL;
|
|
|
|
using static OpenTK.GTKBindingHelper;
|
|
|
|
namespace OpenTK
|
|
{
|
|
public interface IGraphicsContext
|
|
{
|
|
void MakeCurrent();
|
|
void SwapBuffers();
|
|
void ClearCurrent();
|
|
void SwapInterval(int interval);
|
|
}
|
|
|
|
public abstract class GraphicsContext : IGraphicsContext
|
|
{
|
|
public static IntPtr Display{ get; set; }
|
|
|
|
public abstract void MakeCurrent();
|
|
|
|
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)
|
|
{
|
|
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 abstract void SwapInterval(int interval);
|
|
}
|
|
|
|
public class WglGraphicsContext : GraphicsContext
|
|
{
|
|
private delegate int wglSwapIntervalExtDelegate(int interval);
|
|
private static wglSwapIntervalExtDelegate wglSwapIntervalExt = null;
|
|
|
|
private IntPtr _windowHandle;
|
|
private IntPtr _deviceContext;
|
|
|
|
public WglGraphicsContext(IntPtr deviceContext, IntPtr graphicsContext, IntPtr windowHandle = default)
|
|
{
|
|
_deviceContext = deviceContext;
|
|
_graphicsContext = graphicsContext;
|
|
_windowHandle = windowHandle;
|
|
|
|
IntPtr swapIntervalPointer = UnsafeNativeMethods.wglGetProcAddress("wglSwapIntervalEXT");
|
|
|
|
if(swapIntervalPointer != null && swapIntervalPointer != IntPtr.Zero)
|
|
{
|
|
wglSwapIntervalExt = (wglSwapIntervalExtDelegate)Marshal.GetDelegateForFunctionPointer(
|
|
swapIntervalPointer, typeof(wglSwapIntervalExtDelegate));
|
|
}
|
|
}
|
|
|
|
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()
|
|
{
|
|
UnsafeNativeMethods.WglMakeCurrent(_deviceContext, IntPtr.Zero);
|
|
}
|
|
|
|
public override void SwapInterval(int interval)
|
|
{
|
|
wglSwapIntervalExt?.Invoke(interval);
|
|
}
|
|
}
|
|
|
|
public class GlxGraphicsContext : GraphicsContext
|
|
{
|
|
private IntPtr _windowHandle;
|
|
|
|
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);
|
|
}
|
|
|
|
public override void SwapInterval(int interval)
|
|
{
|
|
UnsafeNativeMethods.glXSwapIntervalEXT(interval);
|
|
}
|
|
}
|
|
} |