mirror of
https://github.com/Ryujinx/GLWidget.git
synced 2024-12-22 14:05:38 +00:00
wip
This commit is contained in:
parent
b999bbcfd5
commit
522678c94d
|
@ -35,437 +35,535 @@ using System.ComponentModel;
|
|||
|
||||
|
||||
using OpenTK.Graphics;
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
|
||||
using OpenTK.Platform;
|
||||
|
||||
using Gtk;
|
||||
using Cairo;
|
||||
using GLib;
|
||||
using Gdk;
|
||||
using OpenGL;
|
||||
using System.Diagnostics;
|
||||
using OpenTK.Mathematics;
|
||||
|
||||
namespace OpenTK
|
||||
{
|
||||
[ToolboxItem(true)]
|
||||
public class GLWidget : DrawingArea
|
||||
{
|
||||
private static bool xThreadInit;
|
||||
[ToolboxItem(true)]
|
||||
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; }
|
||||
}
|
||||
#region Static attrs.
|
||||
|
||||
/// <summary>
|
||||
/// The OpenGL color buffer bits.
|
||||
/// </summary>
|
||||
private uint _ColorBits = 24;
|
||||
private static int _graphicsContextCount;
|
||||
private static bool _sharedContextInitialized;
|
||||
|
||||
/// <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.
|
||||
public bool HandleRendering { get; set; } = false;
|
||||
public bool IsRenderHandler { get; set; } = false;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Attributes
|
||||
|
||||
private IGraphicsContext _graphicsContext;
|
||||
private IWindowInfo _windowInfo;
|
||||
private bool _initialized;
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
#region Properties
|
||||
|
||||
/// <summary>The major version of OpenGL to use.</summary>
|
||||
public int GLVersionMajor { get; set; }
|
||||
/// <summary>Use a single buffer versus a double buffer.</summary>
|
||||
[Browsable(true)]
|
||||
public bool SingleBuffer { get; set; }
|
||||
|
||||
/// <summary>The minor version of OpenGL to use.</summary>
|
||||
public int GLVersionMinor { get; set; }
|
||||
/// <summary>Color Buffer Bits-Per-Pixel</summary>
|
||||
public int ColorBPP { get; set; }
|
||||
|
||||
private DeviceContext _deviceContext;
|
||||
private IntPtr _graphicsContext;
|
||||
private int _error;
|
||||
/// <summary>Accumulation Buffer Bits-Per-Pixel</summary>
|
||||
public int AccumulatorBPP { get; set; }
|
||||
|
||||
private IGraphicsContext _context;
|
||||
private GLContext _gdkGlContext;
|
||||
/// <summary>Depth Buffer Bits-Per-Pixel</summary>
|
||||
public int DepthBPP { get; set; }
|
||||
|
||||
public bool ForwardCompatible { get; }
|
||||
public DeviceContext DeviceContext { get => _deviceContext; set => _deviceContext = value; }
|
||||
/// <summary>Stencil Buffer Bits-Per-Pixel</summary>
|
||||
public int StencilBPP { get; set; }
|
||||
|
||||
/// <summary>Number of samples</summary>
|
||||
public int Samples { get; set; }
|
||||
|
||||
/// <summary>Indicates if steropic renderering is enabled</summary>
|
||||
public bool Stereo { get; set; }
|
||||
|
||||
/// <summary>The major version of OpenGL to use.</summary>
|
||||
public int GLVersionMajor { get; set; }
|
||||
|
||||
/// <summary>The minor version of OpenGL to use.</summary>
|
||||
public int GLVersionMinor { get; set; }
|
||||
|
||||
public GraphicsContextFlags GraphicsContextFlags
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Construction/Destruction
|
||||
|
||||
/// <summary>Constructs a new GLWidget</summary>
|
||||
public GLWidget() : this(new Version(4, 0), true)
|
||||
/// <summary>Constructs a new GLWidget.</summary>
|
||||
public GLWidget()
|
||||
: this(GraphicsMode.Default)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Constructs a new GLWidget using a given GraphicsMode</summary>
|
||||
public GLWidget(GraphicsMode graphicsMode)
|
||||
: this(graphicsMode, 1, 0, GraphicsContextFlags.Default)
|
||||
{
|
||||
/*this.ColorBits = 32;
|
||||
this.DepthBits = 24;
|
||||
this.StencilBits = 8;*/
|
||||
}
|
||||
|
||||
/// <summary>Constructs a new GLWidget</summary>
|
||||
public GLWidget(Version apiVersion, bool forwardCompatible)
|
||||
{
|
||||
GLVersionMajor = apiVersion.Major;
|
||||
GLVersionMinor = apiVersion.Minor;
|
||||
ForwardCompatible = forwardCompatible;
|
||||
}
|
||||
public GLWidget(GraphicsMode graphicsMode, int glVersionMajor, int glVersionMinor, GraphicsContextFlags graphicsContextFlags)
|
||||
{
|
||||
SingleBuffer = graphicsMode.Buffers == 1;
|
||||
ColorBPP = graphicsMode.ColorFormat.BitsPerPixel;
|
||||
AccumulatorBPP = graphicsMode.AccumulatorFormat.BitsPerPixel;
|
||||
DepthBPP = graphicsMode.Depth;
|
||||
StencilBPP = graphicsMode.Stencil;
|
||||
Samples = graphicsMode.Samples;
|
||||
Stereo = graphicsMode.Stereo;
|
||||
|
||||
~GLWidget()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
OnShuttingDown();
|
||||
GLVersionMajor = glVersionMajor;
|
||||
GLVersionMinor = glVersionMinor;
|
||||
GraphicsContextFlags = graphicsContextFlags;
|
||||
}
|
||||
|
||||
DeviceContext?.DeleteContext(_graphicsContext);
|
||||
~GLWidget()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
DeviceContext?.Dispose();
|
||||
public void MakeCurrent()
|
||||
{
|
||||
GraphicsContext.MakeCurrent(_windowInfo);
|
||||
}
|
||||
|
||||
_gdkGlContext?.Dispose();
|
||||
public void ClearCurrent()
|
||||
{
|
||||
GraphicsContext.MakeCurrent(null);
|
||||
}
|
||||
|
||||
public void Swapbuffers()
|
||||
{
|
||||
GraphicsContext.SwapBuffers();
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
try
|
||||
{
|
||||
GraphicsContext.MakeCurrent(WindowInfo);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
OnShuttingDown();
|
||||
|
||||
if (OpenTK.Graphics.GraphicsContext.ShareContexts && (Interlocked.Decrement(ref _graphicsContextCount) == 0))
|
||||
{
|
||||
OnGraphicsContextShuttingDown();
|
||||
_sharedContextInitialized = false;
|
||||
}
|
||||
|
||||
GraphicsContext.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region New Events
|
||||
#region New Events
|
||||
|
||||
// Called when the first GraphicsContext is created in the case of GraphicsContext.ShareContexts == True;
|
||||
public static event EventHandler GraphicsContextInitialized;
|
||||
// Called when the first GraphicsContext is created in the case of GraphicsContext.ShareContexts == True;
|
||||
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;
|
||||
public static event EventHandler GraphicsContextShuttingDown;
|
||||
|
||||
private static void OnGraphicsContextShuttingDown()
|
||||
{
|
||||
if (GraphicsContextShuttingDown != null)
|
||||
{
|
||||
GraphicsContextShuttingDown(null, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
// Called when this GLWidget has a valid GraphicsContext
|
||||
public event EventHandler Initialized;
|
||||
|
||||
protected virtual void OnInitialized()
|
||||
{
|
||||
if (Initialized != null)
|
||||
{
|
||||
Initialized(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
// Called when this GLWidget needs to render a frame
|
||||
public event EventHandler RenderFrame;
|
||||
|
||||
protected virtual void OnRenderFrame()
|
||||
{
|
||||
RenderFrame?.Invoke(this, EventArgs.Empty);
|
||||
protected virtual void OnInitialized()
|
||||
{
|
||||
if (Initialized != null)
|
||||
{
|
||||
Initialized(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
// Called when this GLWidget is being Disposed
|
||||
public event EventHandler ShuttingDown;
|
||||
// Called when this GLWidget needs to render a frame
|
||||
public event EventHandler RenderFrame;
|
||||
|
||||
protected virtual void OnShuttingDown()
|
||||
{
|
||||
if (ShuttingDown != null)
|
||||
{
|
||||
ShuttingDown(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
protected virtual void OnRenderFrame()
|
||||
{
|
||||
if (RenderFrame != null)
|
||||
{
|
||||
RenderFrame(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
// Called when this GLWidget is being Disposed
|
||||
public event EventHandler ShuttingDown;
|
||||
|
||||
// Called when the widget needs to be (fully or partially) redrawn.
|
||||
protected virtual void OnShuttingDown()
|
||||
{
|
||||
if (ShuttingDown != null)
|
||||
{
|
||||
ShuttingDown(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool OnDrawn(Cairo.Context cr)
|
||||
{
|
||||
if (!_initialized)
|
||||
Initialize();
|
||||
#endregion
|
||||
|
||||
ClearCurrent();
|
||||
// Called when a widget is realized. (window handles and such are valid)
|
||||
// protected override void OnRealized() { base.OnRealized(); }
|
||||
|
||||
// Called when the widget needs to be (fully or partially) redrawn.
|
||||
|
||||
protected override bool OnDrawn(Cairo.Context cr)
|
||||
{
|
||||
if (!_initialized)
|
||||
Initialize();
|
||||
else if (!IsRenderHandler)
|
||||
GraphicsContext.MakeCurrent(WindowInfo);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Swapbuffers()
|
||||
{
|
||||
_context?.SwapBuffers();
|
||||
}
|
||||
|
||||
public void MakeCurrent()
|
||||
{
|
||||
ClearCurrent();
|
||||
|
||||
_context?.MakeCurrent();
|
||||
|
||||
_error = Marshal.GetLastWin32Error();
|
||||
}
|
||||
|
||||
public void ClearCurrent()
|
||||
{
|
||||
if (GTKBindingHelper.CurrentPlatform == OSPlatform.Windows)
|
||||
{
|
||||
DeviceContext?.MakeCurrent(IntPtr.Zero);
|
||||
}
|
||||
else
|
||||
{
|
||||
Gdk.GLContext.ClearCurrent();
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateContext()
|
||||
{
|
||||
if (_graphicsContext != IntPtr.Zero)
|
||||
throw new InvalidOperationException("context already created");
|
||||
|
||||
IntPtr sharingContext = IntPtr.Zero;
|
||||
|
||||
if (Gl.PlatformExtensions.CreateContext_ARB)
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region WGL_ARB_create_context_robustness|GLX_ARB_create_context_robustness
|
||||
|
||||
if (Gl.PlatformExtensions.CreateContextRobustness_ARB)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
Debug.Assert(Wgl.CONTEXT_FLAGS_ARB == Glx.CONTEXT_FLAGS_ARB);
|
||||
if (contextFlags != 0)
|
||||
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
|
||||
{
|
||||
// Create OpenGL context using compatibility profile
|
||||
if ((_graphicsContext = _deviceContext.CreateContext(sharingContext)) == IntPtr.Zero)
|
||||
throw new InvalidOperationException("unable to create render context");
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateDeviceContext(DevicePixelFormat controlReqFormat)
|
||||
{
|
||||
#region Create device context
|
||||
|
||||
DeviceContext = DeviceContext.Create(GTKBindingHelper.GetDisplayHandle(Display.Handle), GTKBindingHelper.GetWindowHandle(Window.Handle));
|
||||
DeviceContext.IncRef();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Set pixel format
|
||||
|
||||
DevicePixelFormatCollection pixelFormats = DeviceContext.PixelsFormats;
|
||||
List<DevicePixelFormat> matchingPixelFormats = pixelFormats.Choose(controlReqFormat);
|
||||
|
||||
if ((matchingPixelFormats.Count == 0) && controlReqFormat.MultisampleBits > 0)
|
||||
{
|
||||
// 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 CreateGdkGlContext()
|
||||
// Called on Resize
|
||||
protected override bool OnConfigureEvent(Gdk.EventConfigure evnt)
|
||||
{
|
||||
_gdkGlContext = Window.CreateGlContext();
|
||||
if (GraphicsContext != null)
|
||||
{
|
||||
GraphicsContext.Update(WindowInfo);
|
||||
}
|
||||
|
||||
_gdkGlContext.SetRequiredVersion(GLVersionMajor, GLVersionMinor);
|
||||
|
||||
_gdkGlContext.ForwardCompatible = ForwardCompatible;
|
||||
|
||||
_gdkGlContext.SetUseEs(0);
|
||||
|
||||
_gdkGlContext.Realize();
|
||||
|
||||
_gdkGlContext.MakeCurrent();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
ClearCurrent();
|
||||
{
|
||||
_initialized = true;
|
||||
|
||||
Khronos.KhronosApi.LogEnabled = true;
|
||||
|
||||
Window.EnsureNative();
|
||||
|
||||
if (GTKBindingHelper.CurrentPlatform == OSPlatform.Windows)
|
||||
// If this looks uninitialized... initialize.
|
||||
if (ColorBPP == 0)
|
||||
{
|
||||
CreateDeviceContext(ControlPixelFormat);
|
||||
ColorBPP = 32;
|
||||
|
||||
CreateContext();
|
||||
|
||||
DeviceContext.MakeCurrent(_graphicsContext);
|
||||
}
|
||||
else {
|
||||
GraphicsContext.Display = Display.Handle;
|
||||
|
||||
CreateGdkGlContext();
|
||||
if (DepthBPP == 0)
|
||||
{
|
||||
DepthBPP = 16;
|
||||
}
|
||||
}
|
||||
|
||||
_context = GraphicsContext.GetCurrentContext(Window.Handle);
|
||||
ColorFormat colorBufferColorFormat = new ColorFormat(ColorBPP);
|
||||
|
||||
MakeCurrent();
|
||||
ColorFormat accumulationColorFormat = new ColorFormat(AccumulatorBPP);
|
||||
|
||||
GTKBindingHelper.InitializeGlBindings();
|
||||
int buffers = 2;
|
||||
if (SingleBuffer)
|
||||
{
|
||||
buffers--;
|
||||
}
|
||||
|
||||
GraphicsMode graphicsMode = new GraphicsMode(colorBufferColorFormat, DepthBPP, StencilBPP, Samples, accumulationColorFormat, buffers, Stereo);
|
||||
|
||||
this.Window.EnsureNative();
|
||||
|
||||
// IWindowInfo
|
||||
if (OpenTK.Configuration.RunningOnWindows)
|
||||
{
|
||||
WindowInfo = InitializeWindows();
|
||||
}
|
||||
else if (OpenTK.Configuration.RunningOnMacOS)
|
||||
{
|
||||
WindowInfo = InitializeOSX();
|
||||
}
|
||||
else
|
||||
{
|
||||
WindowInfo = InitializeX(graphicsMode);
|
||||
}
|
||||
|
||||
// GraphicsContext
|
||||
GraphicsContext = new GraphicsContext(graphicsMode, WindowInfo, GLVersionMajor, GLVersionMinor, GraphicsContextFlags);
|
||||
GraphicsContext.MakeCurrent(WindowInfo);
|
||||
|
||||
if (OpenTK.Graphics.GraphicsContext.ShareContexts)
|
||||
{
|
||||
Interlocked.Increment(ref _graphicsContextCount);
|
||||
|
||||
if (!_sharedContextInitialized)
|
||||
{
|
||||
_sharedContextInitialized = true;
|
||||
((IGraphicsContextInternal)GraphicsContext).LoadAll();
|
||||
OnGraphicsContextInitialized();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
((IGraphicsContextInternal)GraphicsContext).LoadAll();
|
||||
OnGraphicsContextInitialized();
|
||||
}
|
||||
|
||||
OnInitialized();
|
||||
}
|
||||
|
||||
OpenTK.GraphicsContext.GetCurrentContext(Window.Handle).SwapInterval(1);
|
||||
#region Windows Specific initalization
|
||||
|
||||
ClearCurrent();
|
||||
IWindowInfo InitializeWindows()
|
||||
{
|
||||
IntPtr windowHandle = gdk_win32_window_get_handle(this.Window.Handle);
|
||||
return Utilities.CreateWindowsWindowInfo(windowHandle);
|
||||
}
|
||||
|
||||
_initialized = true;
|
||||
[SuppressUnmanagedCodeSecurity, DllImport("libgdk-3-0.dll")]
|
||||
public static extern IntPtr gdk_win32_window_get_handle(IntPtr d);
|
||||
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region OSX Specific Initialization
|
||||
|
||||
IWindowInfo InitializeOSX()
|
||||
{
|
||||
IntPtr windowHandle = gdk_quartz_window_get_nswindow(this.Window.Handle);
|
||||
//IntPtr viewHandle = gdk_quartz_window_get_nsview(this.GdkWindow.Handle);
|
||||
return Utilities.CreateMacOSWindowInfo(windowHandle);
|
||||
}
|
||||
|
||||
[SuppressUnmanagedCodeSecurity, DllImport("libgdk-3.0.dylib")]
|
||||
static extern IntPtr gdk_quartz_window_get_nswindow(IntPtr handle);
|
||||
|
||||
[SuppressUnmanagedCodeSecurity, DllImport("libgdk-3.0.dylib")]
|
||||
static extern IntPtr gdk_quartz_window_get_nsview(IntPtr handle);
|
||||
|
||||
#endregion
|
||||
|
||||
#region X Specific Initialization
|
||||
|
||||
const string UnixLibGdkName = "libgdk-3.so.0";
|
||||
|
||||
const string UnixLibX11Name = "libX11.so.6";
|
||||
const string UnixLibGLName = "libGL.so.1";
|
||||
|
||||
const int GLX_NONE = 0;
|
||||
const int GLX_USE_GL = 1;
|
||||
const int GLX_BUFFER_SIZE = 2;
|
||||
const int GLX_LEVEL = 3;
|
||||
const int GLX_RGBA = 4;
|
||||
const int GLX_DOUBLEBUFFER = 5;
|
||||
const int GLX_STEREO = 6;
|
||||
const int GLX_AUX_BUFFERS = 7;
|
||||
const int GLX_RED_SIZE = 8;
|
||||
const int GLX_GREEN_SIZE = 9;
|
||||
const int GLX_BLUE_SIZE = 10;
|
||||
const int GLX_ALPHA_SIZE = 11;
|
||||
const int GLX_DEPTH_SIZE = 12;
|
||||
const int GLX_STENCIL_SIZE = 13;
|
||||
const int GLX_ACCUM_RED_SIZE = 14;
|
||||
const int GLX_ACCUM_GREEN_SIZE = 15;
|
||||
const int GLX_ACCUM_BLUE_SIZE = 16;
|
||||
const int GLX_ACCUM_ALPHA_SIZE = 17;
|
||||
|
||||
public enum XVisualClass
|
||||
{
|
||||
StaticGray = 0,
|
||||
GrayScale = 1,
|
||||
StaticColor = 2,
|
||||
PseudoColor = 3,
|
||||
TrueColor = 4,
|
||||
DirectColor = 5,
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
struct XVisualInfo
|
||||
{
|
||||
public IntPtr Visual;
|
||||
public IntPtr VisualID;
|
||||
public int Screen;
|
||||
public int Depth;
|
||||
public XVisualClass Class;
|
||||
public long RedMask;
|
||||
public long GreenMask;
|
||||
public long blueMask;
|
||||
public int ColormapSize;
|
||||
public int BitsPerRgb;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"id ({VisualID}), screen ({Screen}), depth ({Depth}), class ({Class})";
|
||||
}
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum XVisualInfoMask
|
||||
{
|
||||
No = 0x0,
|
||||
ID = 0x1,
|
||||
Screen = 0x2,
|
||||
Depth = 0x4,
|
||||
Class = 0x8,
|
||||
Red = 0x10,
|
||||
Green = 0x20,
|
||||
Blue = 0x40,
|
||||
ColormapSize = 0x80,
|
||||
BitsPerRGB = 0x100,
|
||||
All = 0x1FF,
|
||||
}
|
||||
|
||||
private IWindowInfo InitializeX(GraphicsMode mode)
|
||||
{
|
||||
IntPtr display = gdk_x11_display_get_xdisplay(Display.Handle);
|
||||
int screen = Screen.Number;
|
||||
|
||||
IntPtr windowHandle = gdk_x11_window_get_xid(Window.Handle);
|
||||
IntPtr rootWindow = gdk_x11_window_get_xid(RootWindow.Handle);
|
||||
|
||||
IntPtr visualInfo;
|
||||
|
||||
if (mode.Index.HasValue)
|
||||
{
|
||||
XVisualInfo info = new XVisualInfo();
|
||||
info.VisualID = mode.Index.Value;
|
||||
int dummy;
|
||||
visualInfo = XGetVisualInfo(display, XVisualInfoMask.ID, ref info, out dummy);
|
||||
}
|
||||
else
|
||||
{
|
||||
visualInfo = GetVisualInfo(display);
|
||||
}
|
||||
|
||||
IWindowInfo retval = Utilities.CreateX11WindowInfo(display, screen, windowHandle, rootWindow, visualInfo);
|
||||
XFree(visualInfo);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
private static IntPtr XGetVisualInfo(IntPtr display, XVisualInfoMask vinfo_mask, ref XVisualInfo template, out int nitems)
|
||||
{
|
||||
return XGetVisualInfoInternal(display, (IntPtr)(int)vinfo_mask, ref template, out nitems);
|
||||
}
|
||||
|
||||
private IntPtr GetVisualInfo(IntPtr display)
|
||||
{
|
||||
try
|
||||
{
|
||||
int[] attributes = AttributeList.ToArray();
|
||||
return glXChooseVisual(display, Screen.Number, attributes);
|
||||
}
|
||||
catch (DllNotFoundException e)
|
||||
{
|
||||
throw new DllNotFoundException("OpenGL dll not found!", e);
|
||||
}
|
||||
catch (EntryPointNotFoundException enf)
|
||||
{
|
||||
throw new EntryPointNotFoundException("Glx entry point not found!", enf);
|
||||
}
|
||||
}
|
||||
|
||||
private List<int> AttributeList
|
||||
{
|
||||
get
|
||||
{
|
||||
List<int> attributeList = new List<int>(24);
|
||||
|
||||
attributeList.Add(GLX_RGBA);
|
||||
|
||||
if (!SingleBuffer)
|
||||
attributeList.Add(GLX_DOUBLEBUFFER);
|
||||
|
||||
if (Stereo)
|
||||
attributeList.Add(GLX_STEREO);
|
||||
|
||||
attributeList.Add(GLX_RED_SIZE);
|
||||
attributeList.Add(ColorBPP / 4); // TODO support 16-bit
|
||||
|
||||
attributeList.Add(GLX_GREEN_SIZE);
|
||||
attributeList.Add(ColorBPP / 4); // TODO support 16-bit
|
||||
|
||||
attributeList.Add(GLX_BLUE_SIZE);
|
||||
attributeList.Add(ColorBPP / 4); // TODO support 16-bit
|
||||
|
||||
attributeList.Add(GLX_ALPHA_SIZE);
|
||||
attributeList.Add(ColorBPP / 4); // TODO support 16-bit
|
||||
|
||||
attributeList.Add(GLX_DEPTH_SIZE);
|
||||
attributeList.Add(DepthBPP);
|
||||
|
||||
attributeList.Add(GLX_STENCIL_SIZE);
|
||||
attributeList.Add(StencilBPP);
|
||||
|
||||
attributeList.Add(GLX_ACCUM_RED_SIZE);
|
||||
attributeList.Add(AccumulatorBPP / 4);// TODO support 16-bit
|
||||
|
||||
attributeList.Add(GLX_ACCUM_GREEN_SIZE);
|
||||
attributeList.Add(AccumulatorBPP / 4);// TODO support 16-bit
|
||||
|
||||
attributeList.Add(GLX_ACCUM_BLUE_SIZE);
|
||||
attributeList.Add(AccumulatorBPP / 4);// TODO support 16-bit
|
||||
|
||||
attributeList.Add(GLX_ACCUM_ALPHA_SIZE);
|
||||
attributeList.Add(AccumulatorBPP / 4);// TODO support 16-bit
|
||||
|
||||
attributeList.Add(GLX_NONE);
|
||||
|
||||
return attributeList;
|
||||
}
|
||||
}
|
||||
|
||||
public IGraphicsContext GraphicsContext { get => _graphicsContext; set => _graphicsContext = value; }
|
||||
public IWindowInfo WindowInfo { get => _windowInfo; set => _windowInfo = value; }
|
||||
|
||||
[DllImport(UnixLibX11Name, EntryPoint = "XGetVisualInfo")]
|
||||
private static extern IntPtr XGetVisualInfoInternal(IntPtr display, IntPtr vinfo_mask, ref XVisualInfo template, out int nitems);
|
||||
|
||||
[SuppressUnmanagedCodeSecurity, DllImport(UnixLibX11Name)]
|
||||
private static extern void XFree(IntPtr handle);
|
||||
|
||||
/// <summary> Returns the X resource (window or pixmap) belonging to a GdkDrawable. </summary>
|
||||
/// <remarks> XID gdk_x11_drawable_get_xid(GdkDrawable *drawable); </remarks>
|
||||
/// <param name="gdkDisplay"> The GdkDrawable. </param>
|
||||
/// <returns> The ID of drawable's X resource. </returns>
|
||||
[SuppressUnmanagedCodeSecurity, DllImport(UnixLibGdkName)]
|
||||
private static extern IntPtr gdk_x11_drawable_get_xid(IntPtr gdkDisplay);
|
||||
|
||||
/// <summary> Returns the X resource (window or pixmap) belonging to a GdkDrawable. </summary>
|
||||
/// <remarks> XID gdk_x11_drawable_get_xid(GdkDrawable *drawable); </remarks>
|
||||
/// <param name="gdkDisplay"> The GdkDrawable. </param>
|
||||
/// <returns> The ID of drawable's X resource. </returns>
|
||||
[SuppressUnmanagedCodeSecurity, DllImport(UnixLibGdkName)]
|
||||
private static extern IntPtr gdk_x11_window_get_xid(IntPtr gdkDisplay);
|
||||
|
||||
/// <summary> Returns the X display of a GdkDisplay. </summary>
|
||||
/// <remarks> Display* gdk_x11_display_get_xdisplay(GdkDisplay *display); </remarks>
|
||||
/// <param name="gdkDisplay"> The GdkDrawable. </param>
|
||||
/// <returns> The X Display of the GdkDisplay. </returns>
|
||||
[SuppressUnmanagedCodeSecurity, DllImport(UnixLibGdkName)]
|
||||
private static extern IntPtr gdk_x11_display_get_xdisplay(IntPtr gdkDisplay);
|
||||
|
||||
[SuppressUnmanagedCodeSecurity, DllImport(UnixLibGLName)]
|
||||
private static extern IntPtr glXChooseVisual(IntPtr display, int screen, int[] attr);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -5,11 +5,13 @@
|
|||
<Description>GLWigdet for GTKSharp, using Opentk.</Description>
|
||||
<Version>1.0.3.2</Version>
|
||||
<RepositoryUrl>https://github.com/Ryujinx/GLWidget</RepositoryUrl>
|
||||
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<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.Windowing.Common" Version="4.0.0-pre9.4" />
|
||||
<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.Windowing.Common" Version="4.0.0-pre9.4"/>
|
||||
<PackageReference Include="System.Drawing.Common" Version="4.7.0"/>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -47,32 +47,16 @@ namespace OpenTK
|
|||
{
|
||||
if (CurrentPlatform == OSPlatform.Windows)
|
||||
{
|
||||
var addr = GetProcAddressWgl(procName);
|
||||
if (addr == null || addr == IntPtr.Zero)
|
||||
{
|
||||
var library = UnsafeNativeMethods.LoadLibrary(WglLibrary);
|
||||
|
||||
addr = UnsafeNativeMethods.GetProcAddress(library, procName);
|
||||
}
|
||||
|
||||
if (addr != IntPtr.Zero)
|
||||
{
|
||||
Loaded = true;
|
||||
}
|
||||
return addr;
|
||||
IntPtr library = OpenTK.Platform.Windows.Functions.LoadLibrary(WglLibrary);
|
||||
return OpenTK.Platform.Windows.Functions.GetProcAddress(library, procName);
|
||||
}
|
||||
else if (CurrentPlatform == OSPlatform.Linux)
|
||||
{
|
||||
return GetProcAddressGlx(procName);
|
||||
return OpenTK.Platform.X11.Glx.GetProcAddress(procName);
|
||||
}
|
||||
else if(CurrentPlatform == OSPlatform.OSX)
|
||||
{
|
||||
var osxAddr = GetProcAddressOSX(procName);
|
||||
if (osxAddr != IntPtr.Zero)
|
||||
{
|
||||
Loaded = true;
|
||||
}
|
||||
return osxAddr;
|
||||
return OpenTK.Platform.MacOS.NS.GetAddress(procName);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -6,7 +6,7 @@ using static OpenTK.GTKBindingHelper;
|
|||
|
||||
namespace OpenTK
|
||||
{
|
||||
public interface IGraphicsContext
|
||||
public interface ILegacyGraphicsContext
|
||||
{
|
||||
void MakeCurrent();
|
||||
void SwapBuffers();
|
||||
|
@ -14,7 +14,7 @@ namespace OpenTK
|
|||
void SwapInterval(int interval);
|
||||
}
|
||||
|
||||
public abstract class GraphicsContext : IGraphicsContext
|
||||
public abstract class LegacyGraphicsContext : ILegacyGraphicsContext
|
||||
{
|
||||
public static IntPtr Display{ get; set; }
|
||||
|
||||
|
@ -40,7 +40,7 @@ namespace OpenTK
|
|||
}
|
||||
}
|
||||
|
||||
public static IGraphicsContext GetCurrentContext(IntPtr handle)
|
||||
public static ILegacyGraphicsContext GetCurrentContext(IntPtr handle)
|
||||
{
|
||||
var currentPlatform = CurrentPlatform;
|
||||
|
||||
|
@ -66,7 +66,7 @@ namespace OpenTK
|
|||
public abstract void SwapInterval(int interval);
|
||||
}
|
||||
|
||||
public class WglGraphicsContext : GraphicsContext
|
||||
public class WglGraphicsContext : LegacyGraphicsContext
|
||||
{
|
||||
private delegate int wglSwapIntervalExtDelegate(int interval);
|
||||
private static wglSwapIntervalExtDelegate wglSwapIntervalExt = null;
|
||||
|
@ -120,7 +120,7 @@ namespace OpenTK
|
|||
}
|
||||
}
|
||||
|
||||
public class GlxGraphicsContext : GraphicsContext
|
||||
public class GlxGraphicsContext : LegacyGraphicsContext
|
||||
{
|
||||
private IntPtr _windowHandle;
|
||||
|
||||
|
@ -162,7 +162,7 @@ namespace OpenTK
|
|||
}
|
||||
}
|
||||
|
||||
public class CglGraphicsContext : GraphicsContext
|
||||
public class CglGraphicsContext : LegacyGraphicsContext
|
||||
{
|
||||
private IntPtr _windowHandle;
|
||||
|
||||
|
|
210
GLWidget/OpenTK/BindingsBase.cs
Normal file
210
GLWidget/OpenTK/BindingsBase.cs
Normal file
|
@ -0,0 +1,210 @@
|
|||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2009 the Open Toolkit library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OpenTK
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a common foundation for all flat API bindings and implements the extension loading interface.
|
||||
/// </summary>
|
||||
public abstract class LegacyBindingsBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructs a new BindingsBase instance.
|
||||
/// </summary>
|
||||
public LegacyBindingsBase()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a <see cref="System.Boolean"/> that indicates whether the list of supported extensions may have changed.
|
||||
/// </summary>
|
||||
protected bool RebuildExtensionList { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves an unmanaged function pointer to the specified function.
|
||||
/// </summary>
|
||||
/// <param name="funcname">
|
||||
/// A <see cref="System.String"/> that defines the name of the function.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A <see cref="IntPtr"/> that contains the address of funcname or IntPtr.Zero,
|
||||
/// if the function is not supported by the drivers.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// Note: some drivers are known to return non-zero values for unsupported functions.
|
||||
/// Typical values include 1 and 2 - inheritors are advised to check for and ignore these
|
||||
/// values.
|
||||
/// </remarks>
|
||||
public abstract IntPtr GetAddress(string funcname);
|
||||
|
||||
/// <summary>
|
||||
/// Gets an object that can be used to synchronize access to the bindings implementation.
|
||||
/// </summary>
|
||||
/// <remarks>This object should be unique across bindings but consistent between bindings
|
||||
/// of the same type. For example, ES10.GL, OpenGL.GL and CL10.CL should all return
|
||||
/// unique objects, but all instances of ES10.GL should return the same object.</remarks>
|
||||
protected abstract object SyncRoot { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Marshals a pointer to a null-terminated byte array to a new <c>System.String</c>.
|
||||
/// This method supports OpenTK and is not intended to be called by user code.
|
||||
/// </summary>
|
||||
/// <param name="ptr">A pointer to a null-terminated byte array.</param>
|
||||
/// <returns>
|
||||
/// A <c>System.String</c> with the data from <paramref name="ptr"/>.
|
||||
/// </returns>
|
||||
protected static string MarshalPtrToString(IntPtr ptr)
|
||||
{
|
||||
if (ptr == IntPtr.Zero)
|
||||
{
|
||||
throw new ArgumentException("ptr");
|
||||
}
|
||||
|
||||
unsafe
|
||||
{
|
||||
sbyte* str = (sbyte*)ptr;
|
||||
int len = 0;
|
||||
while (*str != 0)
|
||||
{
|
||||
++len;
|
||||
++str;
|
||||
}
|
||||
|
||||
return new string((sbyte*)ptr, 0, len, Encoding.UTF8);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Marshal a <c>System.String</c> to unmanaged memory.
|
||||
/// The resulting string is encoded in UTF8 and must be freed
|
||||
/// with <c>FreeStringPtr</c>.
|
||||
/// </summary>
|
||||
/// <param name="str">The <c>System.String</c> to marshal.</param>
|
||||
/// <returns>
|
||||
/// An unmanaged pointer containing the marshalled string.
|
||||
/// This pointer must be freed with <c>FreeStringPtr</c>
|
||||
/// </returns>
|
||||
protected static IntPtr MarshalStringToPtr(string str)
|
||||
{
|
||||
if (String.IsNullOrEmpty(str))
|
||||
{
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
// Allocate a buffer big enough to hold the marshalled string.
|
||||
// GetMaxByteCount() appears to allocate space for the final NUL
|
||||
// character, but allocate an extra one just in case (who knows
|
||||
// what old Mono version would do here.)
|
||||
int max_count = Encoding.UTF8.GetMaxByteCount(str.Length) + 1;
|
||||
IntPtr ptr = Marshal.AllocHGlobal(max_count);
|
||||
if (ptr == IntPtr.Zero)
|
||||
{
|
||||
throw new OutOfMemoryException();
|
||||
}
|
||||
|
||||
// Pin the managed string and convert it to UTF8 using
|
||||
// the pointer overload of System.Encoding.UTF8.GetBytes().
|
||||
unsafe
|
||||
{
|
||||
fixed (char* pstr = str)
|
||||
{
|
||||
int actual_count = Encoding.UTF8.GetBytes(pstr, str.Length, (byte*)ptr, max_count);
|
||||
Marshal.WriteByte(ptr, actual_count, 0); // Append '\0' at the end of the string
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Frees a marshalled string that allocated by <c>MarshalStringToPtr</c>.
|
||||
/// </summary>
|
||||
/// <param name="ptr">An unmanaged pointer allocated with <c>MarshalStringToPtr</c></param>
|
||||
protected static void FreeStringPtr(IntPtr ptr)
|
||||
{
|
||||
Marshal.FreeHGlobal(ptr);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Marshals a <c>System.String</c> array to unmanaged memory by calling
|
||||
/// Marshal.AllocHGlobal for each element.
|
||||
/// </summary>
|
||||
/// <returns>An unmanaged pointer to an array of null-terminated strings</returns>
|
||||
/// <param name="str_array">The string array to marshal.</param>
|
||||
protected static IntPtr MarshalStringArrayToPtr(string[] str_array)
|
||||
{
|
||||
IntPtr ptr = IntPtr.Zero;
|
||||
if (str_array != null && str_array.Length != 0)
|
||||
{
|
||||
ptr = Marshal.AllocHGlobal(str_array.Length * IntPtr.Size);
|
||||
if (ptr == IntPtr.Zero)
|
||||
{
|
||||
throw new OutOfMemoryException();
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
try
|
||||
{
|
||||
for (i = 0; i < str_array.Length; i++)
|
||||
{
|
||||
IntPtr str = MarshalStringToPtr(str_array[i]);
|
||||
Marshal.WriteIntPtr(ptr, i * IntPtr.Size, str);
|
||||
}
|
||||
}
|
||||
catch (OutOfMemoryException)
|
||||
{
|
||||
for (i = i - 1; i >= 0; --i)
|
||||
{
|
||||
Marshal.FreeHGlobal(Marshal.ReadIntPtr(ptr, i * IntPtr.Size));
|
||||
}
|
||||
|
||||
Marshal.FreeHGlobal(ptr);
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Frees a marshalled string that allocated by <c>MarshalStringArrayToPtr</c>.
|
||||
/// </summary>
|
||||
/// <param name="ptr">An unmanaged pointer allocated with <c>MarshalStringArrayToPtr</c></param>
|
||||
/// <param name="length">The length of the string array.</param>
|
||||
protected static void FreeStringArrayPtr(IntPtr ptr, int length)
|
||||
{
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
Marshal.FreeHGlobal(Marshal.ReadIntPtr(ptr, i * IntPtr.Size));
|
||||
}
|
||||
Marshal.FreeHGlobal(ptr);
|
||||
}
|
||||
|
||||
internal abstract void LoadEntryPoints();
|
||||
}
|
||||
}
|
197
GLWidget/OpenTK/Configuration.cs
Normal file
197
GLWidget/OpenTK/Configuration.cs
Normal file
|
@ -0,0 +1,197 @@
|
|||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2009 the Open Toolkit library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OpenTK
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides information about the underlying OS and runtime.
|
||||
/// You must call <c>Toolkit.Init</c> before accessing members
|
||||
/// of this class.
|
||||
/// </summary>
|
||||
public sealed class Configuration
|
||||
{
|
||||
private static bool runningOnUnix, runningOnMacOS, runningOnLinux;
|
||||
private volatile static bool initialized;
|
||||
private readonly static object InitLock = new object();
|
||||
|
||||
private Configuration() { }
|
||||
|
||||
/// <summary>Gets a System.Boolean indicating whether OpenTK is running on a Windows platform.</summary>
|
||||
public static bool RunningOnWindows { get; private set; }
|
||||
|
||||
/// <summary>Gets a System.Boolean indicating whether OpenTK is running on an X11 platform.</summary>
|
||||
public static bool RunningOnX11 { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="System.Boolean"/> indicating whether OpenTK is running on a Unix platform.
|
||||
/// </summary>
|
||||
public static bool RunningOnUnix
|
||||
{
|
||||
get { return runningOnUnix; }
|
||||
}
|
||||
|
||||
/// <summary>Gets a System.Boolean indicating whether OpenTK is running on the Linux kernel.</summary>
|
||||
public static bool RunningOnLinux { get { return runningOnLinux; } }
|
||||
|
||||
/// <summary>Gets a System.Boolean indicating whether OpenTK is running on a MacOS platform.</summary>
|
||||
public static bool RunningOnMacOS { get { return runningOnMacOS; } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a System.Boolean indicating whether OpenTK is running on the Mono runtime.
|
||||
/// </summary>
|
||||
public static bool RunningOnMono { get; private set; }
|
||||
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
||||
private struct utsname
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
|
||||
public string sysname;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
|
||||
public string nodename;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
|
||||
public string release;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
|
||||
public string version;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
|
||||
public string machine;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)]
|
||||
public string extraJustInCase;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Detects the unix kernel by p/invoking uname (libc).
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static string DetectUnixKernel()
|
||||
{
|
||||
Debug.Print("Size: {0}", Marshal.SizeOf(typeof(utsname)).ToString());
|
||||
Debug.Flush();
|
||||
utsname uts = new utsname();
|
||||
uname(out uts);
|
||||
|
||||
Debug.WriteLine("System:");
|
||||
Debug.Indent();
|
||||
Debug.WriteLine(uts.sysname);
|
||||
Debug.WriteLine(uts.nodename);
|
||||
Debug.WriteLine(uts.release);
|
||||
Debug.WriteLine(uts.version);
|
||||
Debug.WriteLine(uts.machine);
|
||||
Debug.Unindent();
|
||||
|
||||
return uts.sysname.ToString();
|
||||
}
|
||||
|
||||
[DllImport("libc")]
|
||||
private static extern void uname(out utsname uname_struct);
|
||||
|
||||
private static bool DetectMono()
|
||||
{
|
||||
// Detect the Mono runtime (code taken from http://mono.wikia.com/wiki/Detecting_if_program_is_running_in_Mono).
|
||||
Type t = Type.GetType("Mono.Runtime");
|
||||
return t != null;
|
||||
}
|
||||
|
||||
private static void DetectUnix(out bool unix, out bool linux, out bool macos)
|
||||
{
|
||||
unix = linux = macos = false;
|
||||
|
||||
string kernel_name = DetectUnixKernel();
|
||||
switch (kernel_name)
|
||||
{
|
||||
case null:
|
||||
case "":
|
||||
throw new PlatformNotSupportedException(
|
||||
"Unknown platform. Please file a bug report at https://github.com/opentk/opentk/issues");
|
||||
|
||||
case "Linux":
|
||||
linux = unix = true;
|
||||
break;
|
||||
|
||||
case "Darwin":
|
||||
macos = unix = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
unix = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool DetectWindows()
|
||||
{
|
||||
return
|
||||
System.Environment.OSVersion.Platform == PlatformID.Win32NT ||
|
||||
System.Environment.OSVersion.Platform == PlatformID.Win32S ||
|
||||
System.Environment.OSVersion.Platform == PlatformID.Win32Windows ||
|
||||
System.Environment.OSVersion.Platform == PlatformID.WinCE;
|
||||
}
|
||||
|
||||
private static bool DetectX11()
|
||||
{
|
||||
// Detect whether X is present.
|
||||
try { return OpenTK.Platform.X11.API.DefaultDisplay != IntPtr.Zero; }
|
||||
catch { return false; }
|
||||
}
|
||||
|
||||
// Detects the underlying OS and runtime.
|
||||
internal static void Init(ToolkitOptions options)
|
||||
{
|
||||
lock (InitLock)
|
||||
{
|
||||
if (!initialized)
|
||||
{
|
||||
RunningOnMono = DetectMono();
|
||||
RunningOnWindows = DetectWindows();
|
||||
if (!RunningOnWindows)
|
||||
{
|
||||
DetectUnix(out runningOnUnix, out runningOnLinux, out runningOnMacOS);
|
||||
}
|
||||
|
||||
if ((runningOnLinux) || options.Backend == PlatformBackend.PreferX11)
|
||||
{
|
||||
RunningOnX11 = DetectX11();
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
Debug.Print("Detected configuration: {0} / {1}",
|
||||
RunningOnWindows ? "Windows" : RunningOnLinux ? "Linux" : RunningOnMacOS ? "MacOS" :
|
||||
runningOnUnix ? "Unix" : RunningOnX11 ? "X11" : "Unknown Platform",
|
||||
RunningOnMono ? "Mono" : ".Net");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
127
GLWidget/OpenTK/ContextHandle.cs
Normal file
127
GLWidget/OpenTK/ContextHandle.cs
Normal file
|
@ -0,0 +1,127 @@
|
|||
/* Licensed under the MIT/X11 license.
|
||||
* Copyright (c) 2006-2008 the OpenTK Team.
|
||||
* This notice may not be removed from any source distribution.
|
||||
* See license.txt for licensing detailed licensing details.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace OpenTK
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a handle to an OpenGL or OpenAL context.
|
||||
/// </summary>
|
||||
public struct ContextHandle : IComparable<ContextHandle>, IEquatable<ContextHandle>
|
||||
{
|
||||
private IntPtr handle;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a System.IntPtr that represents the handle of this ContextHandle.
|
||||
/// </summary>
|
||||
public IntPtr Handle { get { return handle; } }
|
||||
|
||||
/// <summary>A read-only field that represents a handle that has been initialized to zero.</summary>
|
||||
public static readonly ContextHandle Zero = new ContextHandle(IntPtr.Zero);
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new instance with the specified handle.
|
||||
/// </summary>
|
||||
/// <param name="h">A System.IntPtr containing the value for this instance.</param>
|
||||
public ContextHandle(IntPtr h) { handle = h; }
|
||||
|
||||
/// <summary>
|
||||
/// Converts this instance to its equivalent string representation.
|
||||
/// </summary>
|
||||
/// <returns>A System.String that contains the string representation of this instance.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return Handle.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares this instance to the specified object.
|
||||
/// </summary>
|
||||
/// <param name="obj">The System.Object to compare to.</param>
|
||||
/// <returns>True if obj is a ContextHandle that is equal to this instance; false otherwise.</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is ContextHandle)
|
||||
{
|
||||
return this.Equals((ContextHandle)obj);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the hash code for this instance.
|
||||
/// </summary>
|
||||
/// <returns>A System.Int32 with the hash code of this instance.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Handle.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the specified ContextHandle to the equivalent IntPtr.
|
||||
/// </summary>
|
||||
/// <param name="c">The ContextHandle to convert.</param>
|
||||
/// <returns>A System.IntPtr equivalent to the specified ContextHandle.</returns>
|
||||
public static explicit operator IntPtr(ContextHandle c)
|
||||
{
|
||||
return c != ContextHandle.Zero ? c.handle : IntPtr.Zero;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the specified IntPtr to the equivalent ContextHandle.
|
||||
/// </summary>
|
||||
/// <param name="p">The System.IntPtr to convert.</param>
|
||||
/// <returns>A ContextHandle equivalent to the specified IntPtr.</returns>
|
||||
public static explicit operator ContextHandle(IntPtr p)
|
||||
{
|
||||
return new ContextHandle(p);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two ContextHandles for equality.
|
||||
/// </summary>
|
||||
/// <param name="left">The ContextHandle to compare.</param>
|
||||
/// <param name="right">The ContextHandle to compare to.</param>
|
||||
/// <returns>True if left is equal to right; false otherwise.</returns>
|
||||
public static bool operator ==(ContextHandle left, ContextHandle right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two ContextHandles for inequality.
|
||||
/// </summary>
|
||||
/// <param name="left">The ContextHandle to compare.</param>
|
||||
/// <param name="right">The ContextHandle to compare to.</param>
|
||||
/// <returns>True if left is not equal to right; false otherwise.</returns>
|
||||
public static bool operator !=(ContextHandle left, ContextHandle right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares the numerical value of this instance to the specified ContextHandle and
|
||||
/// returns a value indicating their relative order.
|
||||
/// </summary>
|
||||
/// <param name="other">The ContextHandle to compare to.</param>
|
||||
/// <returns>Less than 0, if this instance is less than other; 0 if both are equal; Greater than 0 if other is greater than this instance.</returns>
|
||||
public int CompareTo(ContextHandle other)
|
||||
{
|
||||
unsafe { return (int)((int*)other.handle.ToPointer() - (int*)this.handle.ToPointer()); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares this instance to the specified ContextHandle for equality.
|
||||
/// </summary>
|
||||
/// <param name="other">The ContextHandle to compare to.</param>
|
||||
/// <returns>True if this instance is equal to other; false otherwise.</returns>
|
||||
public bool Equals(ContextHandle other)
|
||||
{
|
||||
return Handle == other.Handle;
|
||||
}
|
||||
}
|
||||
}
|
445
GLWidget/OpenTK/DisplayDevice.cs
Normal file
445
GLWidget/OpenTK/DisplayDevice.cs
Normal file
|
@ -0,0 +1,445 @@
|
|||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2010 the Open Toolkit library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
|
||||
namespace OpenTK
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a display device on the underlying system, and provides
|
||||
/// methods to query and change its display parameters.
|
||||
/// </summary>
|
||||
public class DisplayDevice
|
||||
{
|
||||
// TODO: Add properties that describe the 'usable' size of the Display, i.e. the maximized size without the taskbar etc.
|
||||
// TODO: Does not detect changes to primary device.
|
||||
|
||||
private bool primary;
|
||||
private Rectangle bounds;
|
||||
private DisplayResolution current_resolution = new DisplayResolution();
|
||||
private List<DisplayResolution> available_resolutions = new List<DisplayResolution>();
|
||||
private IList<DisplayResolution> available_resolutions_readonly;
|
||||
|
||||
internal object Id; // A platform-specific id for this monitor
|
||||
|
||||
private static readonly object display_lock = new object();
|
||||
private static DisplayDevice primary_display;
|
||||
|
||||
private static Platform.IDisplayDeviceDriver implementation;
|
||||
|
||||
static DisplayDevice()
|
||||
{
|
||||
implementation = Platform.Factory.Default.CreateDisplayDeviceDriver();
|
||||
}
|
||||
|
||||
internal DisplayDevice()
|
||||
{
|
||||
available_resolutions_readonly = available_resolutions.AsReadOnly();
|
||||
}
|
||||
|
||||
internal DisplayDevice(DisplayResolution currentResolution, bool primary,
|
||||
IEnumerable<DisplayResolution> availableResolutions, Rectangle bounds,
|
||||
object id)
|
||||
: this()
|
||||
{
|
||||
// Todo: Consolidate current resolution with bounds? Can they fall out of sync right now?
|
||||
this.current_resolution = currentResolution;
|
||||
IsPrimary = primary;
|
||||
this.available_resolutions.AddRange(availableResolutions);
|
||||
#pragma warning disable 612,618
|
||||
this.bounds = bounds == Rectangle.Empty ? currentResolution.Bounds : bounds;
|
||||
#pragma warning restore 612,618
|
||||
this.Id = id;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the bounds of this instance in pixel coordinates..
|
||||
/// </summary>
|
||||
public Rectangle Bounds
|
||||
{
|
||||
get { return bounds; }
|
||||
internal set
|
||||
{
|
||||
bounds = value;
|
||||
current_resolution.Height = bounds.Height;
|
||||
current_resolution.Width = bounds.Width;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets a System.Int32 that contains the width of this display in pixels.</summary>
|
||||
public int Width { get { return current_resolution.Width; } }
|
||||
|
||||
/// <summary>Gets a System.Int32 that contains the height of this display in pixels.</summary>
|
||||
public int Height { get { return current_resolution.Height; } }
|
||||
|
||||
/// <summary>Gets a System.Int32 that contains number of bits per pixel of this display. Typical values include 8, 16, 24 and 32.</summary>
|
||||
public int BitsPerPixel
|
||||
{
|
||||
get { return current_resolution.BitsPerPixel; }
|
||||
internal set { current_resolution.BitsPerPixel = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a System.Single representing the vertical refresh rate of this display.
|
||||
/// </summary>
|
||||
public float RefreshRate
|
||||
{
|
||||
get { return current_resolution.RefreshRate; }
|
||||
internal set { current_resolution.RefreshRate = value; }
|
||||
}
|
||||
|
||||
/// <summary>Gets a System.Boolean that indicates whether this Display is the primary Display in systems with multiple Displays.</summary>
|
||||
public bool IsPrimary
|
||||
{
|
||||
get { return primary; }
|
||||
internal set
|
||||
{
|
||||
if (value && primary_display != null && primary_display != this)
|
||||
{
|
||||
primary_display.IsPrimary = false;
|
||||
}
|
||||
|
||||
lock (display_lock)
|
||||
{
|
||||
primary = value;
|
||||
if (value)
|
||||
{
|
||||
primary_display = this;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Selects an available resolution that matches the specified parameters.
|
||||
/// </summary>
|
||||
/// <param name="width">The width of the requested resolution in pixels.</param>
|
||||
/// <param name="height">The height of the requested resolution in pixels.</param>
|
||||
/// <param name="bitsPerPixel">The bits per pixel of the requested resolution.</param>
|
||||
/// <param name="refreshRate">The refresh rate of the requested resolution in hertz.</param>
|
||||
/// <returns>The requested DisplayResolution or null if the parameters cannot be met.</returns>
|
||||
/// <remarks>
|
||||
/// <para>If a matching resolution is not found, this function will retry ignoring the specified refresh rate,
|
||||
/// bits per pixel and resolution, in this order. If a matching resolution still doesn't exist, this function will
|
||||
/// return the current resolution.</para>
|
||||
/// <para>A parameter set to 0 or negative numbers will not be used in the search (e.g. if refreshRate is 0,
|
||||
/// any refresh rate will be considered valid).</para>
|
||||
/// <para>This function allocates memory.</para>
|
||||
/// </remarks>
|
||||
public DisplayResolution SelectResolution(int width, int height, int bitsPerPixel, float refreshRate)
|
||||
{
|
||||
DisplayResolution resolution = FindResolution(width, height, bitsPerPixel, refreshRate);
|
||||
if (resolution == null)
|
||||
{
|
||||
resolution = FindResolution(width, height, bitsPerPixel, 0);
|
||||
}
|
||||
if (resolution == null)
|
||||
{
|
||||
resolution = FindResolution(width, height, 0, 0);
|
||||
}
|
||||
if (resolution == null)
|
||||
{
|
||||
return current_resolution;
|
||||
}
|
||||
return resolution;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of <see cref="DisplayResolution"/> objects available on this device.
|
||||
/// </summary>
|
||||
public IList<DisplayResolution> AvailableResolutions
|
||||
{
|
||||
get { return available_resolutions_readonly; }
|
||||
internal set
|
||||
{
|
||||
available_resolutions = (List<DisplayResolution>)value;
|
||||
available_resolutions_readonly = available_resolutions.AsReadOnly();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Changes the resolution of the DisplayDevice.</summary>
|
||||
/// <param name="resolution">The resolution to set. <see cref="DisplayDevice.SelectResolution"/></param>
|
||||
/// <exception cref="Graphics.GraphicsModeException">Thrown if the requested resolution could not be set.</exception>
|
||||
/// <remarks>If the specified resolution is null, this function will restore the original DisplayResolution.</remarks>
|
||||
public void ChangeResolution(DisplayResolution resolution)
|
||||
{
|
||||
if (resolution == null)
|
||||
{
|
||||
this.RestoreResolution();
|
||||
}
|
||||
|
||||
if (resolution == current_resolution)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//effect.FadeOut();
|
||||
|
||||
if (implementation.TryChangeResolution(this, resolution))
|
||||
{
|
||||
if (OriginalResolution == null)
|
||||
{
|
||||
OriginalResolution = current_resolution;
|
||||
}
|
||||
current_resolution = resolution;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Graphics.GraphicsModeException(String.Format("Device {0}: Failed to change resolution to {1}.",
|
||||
this, resolution));
|
||||
}
|
||||
|
||||
//effect.FadeIn();
|
||||
}
|
||||
|
||||
/// <summary>Changes the resolution of the DisplayDevice.</summary>
|
||||
/// <param name="width">The new width of the DisplayDevice.</param>
|
||||
/// <param name="height">The new height of the DisplayDevice.</param>
|
||||
/// <param name="bitsPerPixel">The new bits per pixel of the DisplayDevice.</param>
|
||||
/// <param name="refreshRate">The new refresh rate of the DisplayDevice.</param>
|
||||
/// <exception cref="Graphics.GraphicsModeException">Thrown if the requested resolution could not be set.</exception>
|
||||
public void ChangeResolution(int width, int height, int bitsPerPixel, float refreshRate)
|
||||
{
|
||||
this.ChangeResolution(this.SelectResolution(width, height, bitsPerPixel, refreshRate));
|
||||
}
|
||||
|
||||
/// <summary>Restores the original resolution of the DisplayDevice.</summary>
|
||||
/// <exception cref="Graphics.GraphicsModeException">Thrown if the original resolution could not be restored.</exception>
|
||||
public void RestoreResolution()
|
||||
{
|
||||
if (OriginalResolution != null)
|
||||
{
|
||||
//effect.FadeOut();
|
||||
|
||||
if (implementation.TryRestoreResolution(this))
|
||||
{
|
||||
current_resolution = OriginalResolution;
|
||||
OriginalResolution = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Graphics.GraphicsModeException(String.Format("Device {0}: Failed to restore resolution.", this));
|
||||
}
|
||||
|
||||
//effect.FadeIn();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets the default (primary) display of this system.</summary>
|
||||
public static DisplayDevice Default
|
||||
{
|
||||
get { return implementation.GetDisplay(DisplayIndex.Primary); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="DisplayDevice"/> for the specified <see cref="DisplayIndex"/>.
|
||||
/// </summary>
|
||||
/// <param name="index">The <see cref="DisplayIndex"/> that defines the desired display.</param>
|
||||
/// <returns>A <see cref="DisplayDevice"/> or null, if no device corresponds to the specified index.</returns>
|
||||
public static DisplayDevice GetDisplay(DisplayIndex index)
|
||||
{
|
||||
return implementation.GetDisplay(index);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the original resolution of this instance.
|
||||
/// </summary>
|
||||
internal DisplayResolution OriginalResolution { get; set; }
|
||||
|
||||
internal static DisplayDevice FromPoint(int x, int y)
|
||||
{
|
||||
for (DisplayIndex i = DisplayIndex.First; i < DisplayIndex.Sixth; i++)
|
||||
{
|
||||
DisplayDevice display = DisplayDevice.GetDisplay(i);
|
||||
if (display != null)
|
||||
{
|
||||
if (display.Bounds.Contains(x, y))
|
||||
{
|
||||
return display;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private DisplayResolution FindResolution(int width, int height, int bitsPerPixel, float refreshRate)
|
||||
{
|
||||
return available_resolutions.Find(delegate(DisplayResolution test)
|
||||
{
|
||||
return
|
||||
((width > 0 && width == test.Width) || width == 0) &&
|
||||
((height > 0 && height == test.Height) || height == 0) &&
|
||||
((bitsPerPixel > 0 && bitsPerPixel == test.BitsPerPixel) || bitsPerPixel == 0) &&
|
||||
((refreshRate > 0 && System.Math.Abs(refreshRate - test.RefreshRate) < 1.0) || refreshRate == 0);
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a System.String representing this DisplayDevice.
|
||||
/// </summary>
|
||||
/// <returns>A System.String representing this DisplayDevice.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("{0}: {1} ({2} modes available)", IsPrimary ? "Primary" : "Secondary",
|
||||
Bounds.ToString(), available_resolutions.Count);
|
||||
}
|
||||
|
||||
///// <summary>Determines whether the specified DisplayDevices are equal.</summary>
|
||||
///// <param name="obj">The System.Object to check against.</param>
|
||||
///// <returns>True if the System.Object is an equal DisplayDevice; false otherwise.</returns>
|
||||
//public override bool Equals(object obj)
|
||||
//{
|
||||
// if (obj is DisplayDevice)
|
||||
// {
|
||||
// DisplayDevice dev = (DisplayDevice)obj;
|
||||
// return
|
||||
// IsPrimary == dev.IsPrimary &&
|
||||
// current_resolution == dev.current_resolution &&
|
||||
// available_resolutions.Count == dev.available_resolutions.Count;
|
||||
// }
|
||||
|
||||
// return false;
|
||||
//}
|
||||
|
||||
///// <summary>Returns a unique hash representing this DisplayDevice.</summary>
|
||||
///// <returns>A System.Int32 that may serve as a hash code for this DisplayDevice.</returns>
|
||||
////public override int GetHashCode()
|
||||
//{
|
||||
// return current_resolution.GetHashCode() ^ IsPrimary.GetHashCode() ^ available_resolutions.Count;
|
||||
//}
|
||||
}
|
||||
#if false
|
||||
class FadeEffect : IDisposable
|
||||
{
|
||||
List<Form> forms = new List<Form>();
|
||||
double opacity_step = 0.04;
|
||||
int sleep_step;
|
||||
|
||||
internal FadeEffect()
|
||||
{
|
||||
foreach (Screen s in Screen.AllScreens)
|
||||
{
|
||||
Form form = new Form();
|
||||
form.ShowInTaskbar = false;
|
||||
form.StartPosition = FormStartPosition.Manual;
|
||||
form.WindowState = FormWindowState.Maximized;
|
||||
form.FormBorderStyle = FormBorderStyle.None;
|
||||
form.TopMost = true;
|
||||
|
||||
form.BackColor = System.Drawing.Color.Black;
|
||||
forms.Add(form);
|
||||
}
|
||||
|
||||
sleep_step = 10 / forms.Count;
|
||||
MoveToStartPositions();
|
||||
}
|
||||
|
||||
void MoveToStartPositions()
|
||||
{
|
||||
int count = 0;
|
||||
foreach (Screen s in Screen.AllScreens)
|
||||
{
|
||||
// forms[count++].Location = new System.Drawing.Point(s.Bounds.X, s.Bounds.Y);
|
||||
//forms[count].Size = new System.Drawing.Size(4096, 4096);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
bool FadedOut
|
||||
{
|
||||
get
|
||||
{
|
||||
bool ready = true;
|
||||
foreach (Form form in forms)
|
||||
ready = ready && form.Opacity >= 1.0;
|
||||
|
||||
return ready;
|
||||
}
|
||||
}
|
||||
|
||||
bool FadedIn
|
||||
{
|
||||
get
|
||||
{
|
||||
bool ready = true;
|
||||
foreach (Form form in forms)
|
||||
ready = ready && form.Opacity <= 0.0;
|
||||
|
||||
return ready;
|
||||
}
|
||||
}
|
||||
|
||||
internal void FadeOut()
|
||||
{
|
||||
MoveToStartPositions();
|
||||
|
||||
foreach (Form form in forms)
|
||||
{
|
||||
form.Opacity = 0.0;
|
||||
form.Visible = true;
|
||||
}
|
||||
|
||||
while (!FadedOut)
|
||||
{
|
||||
foreach (Form form in forms)
|
||||
{
|
||||
form.Opacity += opacity_step;
|
||||
form.Refresh();
|
||||
}
|
||||
Thread.Sleep(sleep_step);
|
||||
}
|
||||
}
|
||||
|
||||
internal void FadeIn()
|
||||
{
|
||||
MoveToStartPositions();
|
||||
|
||||
foreach (Form form in forms)
|
||||
form.Opacity = 1.0;
|
||||
|
||||
while (!FadedIn)
|
||||
{
|
||||
foreach (Form form in forms)
|
||||
{
|
||||
form.Opacity -= opacity_step;
|
||||
form.Refresh();
|
||||
}
|
||||
Thread.Sleep(sleep_step);
|
||||
}
|
||||
|
||||
foreach (Form form in forms)
|
||||
form.Visible = false;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (Form form in forms)
|
||||
form.Dispose();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
66
GLWidget/OpenTK/DisplayIndex.cs
Normal file
66
GLWidget/OpenTK/DisplayIndex.cs
Normal file
|
@ -0,0 +1,66 @@
|
|||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2010 the Open Toolkit library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
namespace OpenTK
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines <see cref="DisplayDevice"/> indices.
|
||||
/// </summary>
|
||||
public enum DisplayIndex
|
||||
{
|
||||
/// <summary>
|
||||
/// The first DisplayDevice.
|
||||
/// </summary>
|
||||
First = 0,
|
||||
/// <summary>
|
||||
/// The second DisplayDevice.
|
||||
/// </summary>
|
||||
Second,
|
||||
/// <summary>
|
||||
/// The third DisplayDevice.
|
||||
/// </summary>
|
||||
Third,
|
||||
/// <summary>
|
||||
/// The fourth DisplayDevice.
|
||||
/// </summary>
|
||||
Fourth,
|
||||
/// <summary>
|
||||
/// The fifth DisplayDevice.
|
||||
/// </summary>
|
||||
Fifth,
|
||||
/// <summary>
|
||||
/// The sixth DisplayDevice.
|
||||
/// </summary>
|
||||
Sixth,
|
||||
/// <summary>
|
||||
/// The default (primary) DisplayDevice.
|
||||
/// </summary>
|
||||
Primary = -1,
|
||||
/// <summary>
|
||||
/// The default (primary) DisplayDevice.
|
||||
/// </summary>
|
||||
Default = Primary,
|
||||
}
|
||||
}
|
179
GLWidget/OpenTK/DisplayResolution.cs
Normal file
179
GLWidget/OpenTK/DisplayResolution.cs
Normal file
|
@ -0,0 +1,179 @@
|
|||
/* Licensed under the MIT/X11 license.
|
||||
* Copyright (c) 2006-2008 the OpenTK team.
|
||||
* This notice may not be removed.
|
||||
* See license.txt for licensing detailed licensing details.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
|
||||
namespace OpenTK
|
||||
{
|
||||
/// <summary>Contains information regarding a monitor's display resolution.</summary>
|
||||
public class DisplayResolution
|
||||
{
|
||||
private Rectangle bounds;
|
||||
|
||||
internal DisplayResolution() { }
|
||||
|
||||
// Creates a new DisplayResolution object for the primary DisplayDevice.
|
||||
internal DisplayResolution(int x, int y, int width, int height, int bitsPerPixel, float refreshRate)
|
||||
{
|
||||
// Refresh rate may be zero, since this information may not be available on some platforms.
|
||||
if (width <= 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("width", "Must be greater than zero.");
|
||||
}
|
||||
if (height <= 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("height", "Must be greater than zero.");
|
||||
}
|
||||
if (bitsPerPixel <= 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("bitsPerPixel", "Must be greater than zero.");
|
||||
}
|
||||
if (refreshRate < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("refreshRate", "Must be greater than, or equal to zero.");
|
||||
}
|
||||
|
||||
this.bounds = new Rectangle(x, y, width, height);
|
||||
this.BitsPerPixel = bitsPerPixel;
|
||||
this.RefreshRate = refreshRate;
|
||||
}
|
||||
|
||||
#if false
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new DisplayResolution object for the specified DisplayDevice.
|
||||
/// </summary>
|
||||
/// <param name="width">The requested width in pixels.</param>
|
||||
/// <param name="height">The requested height in pixels.</param>
|
||||
/// <param name="bitsPerPixel">The requested bits per pixel in bits.</param>
|
||||
/// <param name="refreshRate">The requested refresh rate in hertz.</param>
|
||||
/// <remarks>OpenTK will select the closest match between all available resolutions on the specified DisplayDevice.</remarks>
|
||||
///
|
||||
public DisplayResolution(int width, int height, int bitsPerPixel, float refreshRate, DisplayDevice device)
|
||||
{
|
||||
// Refresh rate may be zero, since this information may not be available on some platforms.
|
||||
if (width <= 0) throw new ArgumentOutOfRangeException("width", "Must be greater than zero.");
|
||||
if (height <= 0) throw new ArgumentOutOfRangeException("height", "Must be greater than zero.");
|
||||
if (bitsPerPixel <= 0) throw new ArgumentOutOfRangeException("bitsPerPixel", "Must be greater than zero.");
|
||||
if (refreshRate < 0) throw new ArgumentOutOfRangeException("refreshRate", "Must be greater than, or equal to zero.");
|
||||
if (device == null) throw new ArgumentNullException("DisplayDevice", "Must be a valid DisplayDevice");
|
||||
|
||||
DisplayResolution res = device.SelectResolution(width, height, bitsPerPixel, refreshRate);
|
||||
|
||||
this.width = res.width;
|
||||
this.height = res.height;
|
||||
this.bits_per_pixel = res.bits_per_pixel;
|
||||
this.refresh_rate = res.refresh_rate;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Gets a System.Drawing.Rectangle that contains the bounds of this display device.
|
||||
/// </summary>
|
||||
[Obsolete("This property will return invalid results if a monitor changes resolution. Use DisplayDevice.Bounds instead.")]
|
||||
[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
|
||||
public Rectangle Bounds
|
||||
{
|
||||
get { return bounds; }
|
||||
}
|
||||
|
||||
/// <summary>Gets a System.Int32 that contains the width of this display in pixels.</summary>
|
||||
public int Width
|
||||
{
|
||||
get { return bounds.Width; }
|
||||
internal set { bounds.Width = value; }
|
||||
}
|
||||
|
||||
/// <summary>Gets a System.Int32 that contains the height of this display in pixels.</summary>
|
||||
public int Height
|
||||
{
|
||||
get { return bounds.Height; }
|
||||
internal set { bounds.Height = value; }
|
||||
}
|
||||
|
||||
/// <summary>Gets a System.Int32 that contains number of bits per pixel of this display. Typical values include 8, 16, 24 and 32.</summary>
|
||||
public int BitsPerPixel { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a System.Single representing the vertical refresh rate of this display.
|
||||
/// </summary>
|
||||
public float RefreshRate { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns a System.String representing this DisplayResolution.
|
||||
/// </summary>
|
||||
/// <returns>A System.String representing this DisplayResolution.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
#pragma warning disable 612,618
|
||||
return String.Format("{0}x{1}@{2}Hz", Bounds, BitsPerPixel, RefreshRate);
|
||||
#pragma warning restore 612,618
|
||||
}
|
||||
|
||||
/// <summary>Determines whether the specified resolutions are equal.</summary>
|
||||
/// <param name="obj">The System.Object to check against.</param>
|
||||
/// <returns>True if the System.Object is an equal DisplayResolution; false otherwise.</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (this.GetType() == obj.GetType())
|
||||
{
|
||||
DisplayResolution res = (DisplayResolution)obj;
|
||||
return
|
||||
Width == res.Width &&
|
||||
Height == res.Height &&
|
||||
BitsPerPixel == res.BitsPerPixel &&
|
||||
RefreshRate == res.RefreshRate;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>Returns a unique hash representing this resolution.</summary>
|
||||
/// <returns>A System.Int32 that may serve as a hash code for this resolution.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
#pragma warning disable 612,618
|
||||
return Bounds.GetHashCode() ^ BitsPerPixel ^ RefreshRate.GetHashCode();
|
||||
#pragma warning restore 612,618
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instances for equality.
|
||||
/// </summary>
|
||||
/// <param name="left">The first instance.</param>
|
||||
/// <param name="right">The second instance.</param>
|
||||
/// <returns>True, if left equals right; false otherwise.</returns>
|
||||
public static bool operator== (DisplayResolution left, DisplayResolution right)
|
||||
{
|
||||
if (((object)left) == null && ((object)right) == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if ((((object)left) == null && ((object)right) != null) ||
|
||||
(((object)left) != null && ((object)right) == null))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instances for inequality.
|
||||
/// </summary>
|
||||
/// <param name="left">The first instance.</param>
|
||||
/// <param name="right">The second instance.</param>
|
||||
/// <returns>True, if left does not equal right; false otherwise.</returns>
|
||||
public static bool operator !=(DisplayResolution left, DisplayResolution right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
}
|
||||
}
|
50
GLWidget/OpenTK/Exceptions.cs
Normal file
50
GLWidget/OpenTK/Exceptions.cs
Normal file
|
@ -0,0 +1,50 @@
|
|||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2009 the Open Toolkit library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
|
||||
namespace OpenTK
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// This exception is thrown when a GraphicsContext property cannot be changed after creation.
|
||||
/// </summary>
|
||||
public class ContextExistsException : ApplicationException
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructs a new ContextExistsException instance.
|
||||
/// </summary>
|
||||
/// <param name="message">A System.String explaining the cause of this exception.</param>
|
||||
public ContextExistsException(string message)
|
||||
{
|
||||
Message = message;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a System.String explaining the cause of this exception.
|
||||
/// </summary>
|
||||
public override string Message { get; }
|
||||
}
|
||||
}
|
281
GLWidget/OpenTK/Graphics/ColorFormat.cs
Normal file
281
GLWidget/OpenTK/Graphics/ColorFormat.cs
Normal file
|
@ -0,0 +1,281 @@
|
|||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2010 the Open Toolkit library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
|
||||
namespace OpenTK.Graphics
|
||||
{
|
||||
/// <summary>Defines the ColorFormat component of a GraphicsMode.</summary>
|
||||
/// <remarks>
|
||||
/// <para>A ColorFormat contains Red, Green, Blue and Alpha components that descibe
|
||||
/// the allocated bits per pixel for the corresponding color.</para>
|
||||
/// </remarks>
|
||||
public struct ColorFormat : IComparable<ColorFormat>, IEquatable<ColorFormat>
|
||||
{
|
||||
private byte red, green, blue, alpha;
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new ColorFormat with the specified aggregate bits per pixel.
|
||||
/// </summary>
|
||||
/// <param name="bpp">The bits per pixel sum for the Red, Green, Blue and Alpha color channels.</param>
|
||||
public ColorFormat(int bpp)
|
||||
{
|
||||
if (bpp < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("bpp", "Must be greater or equal to zero.");
|
||||
}
|
||||
red = green = blue = alpha = 0;
|
||||
BitsPerPixel = bpp;
|
||||
IsIndexed = false;
|
||||
|
||||
switch (bpp)
|
||||
{
|
||||
case 32:
|
||||
Red = Green = Blue = Alpha = 8;
|
||||
break;
|
||||
case 24:
|
||||
Red = Green = Blue = 8;
|
||||
break;
|
||||
case 16:
|
||||
Red = Blue = 5;
|
||||
Green = 6;
|
||||
break;
|
||||
case 15:
|
||||
Red = Green = Blue = 5;
|
||||
break;
|
||||
case 8:
|
||||
Red = Green = 3;
|
||||
Blue = 2;
|
||||
IsIndexed = true;
|
||||
break;
|
||||
case 4:
|
||||
Red = Green = 2;
|
||||
Blue = 1;
|
||||
IsIndexed = true;
|
||||
break;
|
||||
case 1:
|
||||
IsIndexed = true;
|
||||
break;
|
||||
default:
|
||||
Red = Blue = Alpha = (byte)(bpp / 4);
|
||||
Green = (byte)((bpp / 4) + (bpp % 4));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new ColorFormat with the specified bits per pixel for
|
||||
/// the Red, Green, Blue and Alpha color channels.
|
||||
/// </summary>
|
||||
/// <param name="red">Bits per pixel for the Red color channel.</param>
|
||||
/// <param name="green">Bits per pixel for the Green color channel.</param>
|
||||
/// <param name="blue">Bits per pixel for the Blue color channel.</param>
|
||||
/// <param name="alpha">Bits per pixel for the Alpha color channel.</param>
|
||||
public ColorFormat(int red, int green, int blue, int alpha)
|
||||
{
|
||||
if (red < 0 || green < 0 || blue < 0 || alpha < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("Arguments must be greater or equal to zero.");
|
||||
}
|
||||
this.red = (byte)red;
|
||||
this.green = (byte)green;
|
||||
this.blue = (byte)blue;
|
||||
this.alpha = (byte)alpha;
|
||||
this.BitsPerPixel = red + green + blue + alpha;
|
||||
this.IsIndexed = false;
|
||||
if (this.BitsPerPixel < 15 && this.BitsPerPixel != 0)
|
||||
{
|
||||
this.IsIndexed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets the bits per pixel for the Red channel.</summary>
|
||||
public int Red { get { return red; } private set { red = (byte)value; } }
|
||||
/// <summary>Gets the bits per pixel for the Green channel.</summary>
|
||||
public int Green { get { return green; } private set { green = (byte)value; } }
|
||||
/// <summary>Gets the bits per pixel for the Blue channel.</summary>
|
||||
public int Blue { get { return blue; } private set { blue = (byte)value; } }
|
||||
/// <summary>Gets the bits per pixel for the Alpha channel.</summary>
|
||||
public int Alpha { get { return alpha; } private set { alpha = (byte)value; } }
|
||||
/// <summary>Gets a System.Boolean indicating whether this ColorFormat is indexed.</summary>
|
||||
public bool IsIndexed { get; private set; }
|
||||
|
||||
/// <summary>Gets the sum of Red, Green, Blue and Alpha bits per pixel.</summary>
|
||||
public int BitsPerPixel { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Defines an empty ColorFormat, where all properties are set to zero.
|
||||
/// </summary>
|
||||
public static readonly ColorFormat Empty = new ColorFormat(0);
|
||||
|
||||
/// <summary>
|
||||
/// Converts the specified bpp into a new ColorFormat.
|
||||
/// </summary>
|
||||
/// <param name="bpp">The bits per pixel to convert.</param>
|
||||
/// <returns>A ColorFormat with the specified bits per pixel.</returns>
|
||||
public static implicit operator ColorFormat(int bpp)
|
||||
{
|
||||
return new ColorFormat(bpp);
|
||||
}
|
||||
|
||||
//public static implicit operator int(ColorFormat mode)
|
||||
//{
|
||||
// return mode.BitsPerPixel;
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instances.
|
||||
/// </summary>
|
||||
/// <param name="other">The other instance.</param>
|
||||
/// <returns>
|
||||
/// Zero if this instance is equal to other;
|
||||
/// a positive value if this instance is greater than other;
|
||||
/// a negative value otherwise.
|
||||
/// </returns>
|
||||
public int CompareTo(ColorFormat other)
|
||||
{
|
||||
int result = BitsPerPixel.CompareTo(other.BitsPerPixel);
|
||||
if (result != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
result = IsIndexed.CompareTo(other.IsIndexed);
|
||||
if (result != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
result = Alpha.CompareTo(other.Alpha);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares whether this ColorFormat structure is equal to the specified ColorFormat.
|
||||
/// </summary>
|
||||
/// <param name="other">The ColorFormat structure to compare to.</param>
|
||||
/// <returns>True if both ColorFormat structures contain the same components; false otherwise.</returns>
|
||||
public bool Equals(ColorFormat other)
|
||||
{
|
||||
return
|
||||
Red == other.Red &&
|
||||
Green == other.Green &&
|
||||
Blue == other.Blue &&
|
||||
Alpha == other.Alpha;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether this instance and a specified object are equal.
|
||||
/// </summary>
|
||||
/// <param name="obj">Another object to compare to.</param>
|
||||
/// <returns>True if this instance is equal to obj; false otherwise.</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return (obj is ColorFormat) ? this.Equals((ColorFormat)obj) : false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instances for equality.
|
||||
/// </summary>
|
||||
/// <param name="left">The left operand.</param>
|
||||
/// <param name="right">The right operand.</param>
|
||||
/// <returns>True if both instances are equal; false otherwise.</returns>
|
||||
public static bool operator ==(ColorFormat left, ColorFormat right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instances for inequality.
|
||||
/// </summary>
|
||||
/// <param name="left">The left operand.</param>
|
||||
/// <param name="right">The right operand.</param>
|
||||
/// <returns>True if both instances are not equal; false otherwise.</returns>
|
||||
public static bool operator !=(ColorFormat left, ColorFormat right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instances for inequality.
|
||||
/// </summary>
|
||||
/// <param name="left">The left operand.</param>
|
||||
/// <param name="right">The right operand.</param>
|
||||
/// <returns>True if left is greater than right; false otherwise.</returns>
|
||||
public static bool operator >(ColorFormat left, ColorFormat right)
|
||||
{
|
||||
return left.CompareTo(right) > 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instances for inequality.
|
||||
/// </summary>
|
||||
/// <param name="left">The left operand.</param>
|
||||
/// <param name="right">The right operand.</param>
|
||||
/// <returns>True if left is greater than or equal to right; false otherwise.</returns>
|
||||
public static bool operator >=(ColorFormat left, ColorFormat right)
|
||||
{
|
||||
return left.CompareTo(right) >= 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instances for inequality.
|
||||
/// </summary>
|
||||
/// <param name="left">The left operand.</param>
|
||||
/// <param name="right">The right operand.</param>
|
||||
/// <returns>True if left is less than right; false otherwise.</returns>
|
||||
public static bool operator <(ColorFormat left, ColorFormat right)
|
||||
{
|
||||
return left.CompareTo(right) < 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instances for inequality.
|
||||
/// </summary>
|
||||
/// <param name="left">The left operand.</param>
|
||||
/// <param name="right">The right operand.</param>
|
||||
/// <returns>True if left is less than or equal to right; false otherwise.</returns>
|
||||
public static bool operator <=(ColorFormat left, ColorFormat right)
|
||||
{
|
||||
return left.CompareTo(right) <= 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the hash code for this instance.
|
||||
/// </summary>
|
||||
/// <returns>A System.Int32 with the hash code of this instance.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Red ^ Green ^ Blue ^ Alpha;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="System.String"/> that describes this instance.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="System.String"/> that describes this instance.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("{0} ({1})", BitsPerPixel, (IsIndexed ? " indexed" : Red.ToString() + Green.ToString() + Blue.ToString() + Alpha.ToString()));
|
||||
}
|
||||
}
|
||||
}
|
94
GLWidget/OpenTK/Graphics/GraphicsBindingsBase.cs
Normal file
94
GLWidget/OpenTK/Graphics/GraphicsBindingsBase.cs
Normal file
|
@ -0,0 +1,94 @@
|
|||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2009 the Open Toolkit library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using OpenTK;
|
||||
|
||||
namespace OpenTK.Graphics
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements BindingsBase for the OpenTK.Graphics namespace (OpenGL and OpenGL|ES).
|
||||
/// </summary>
|
||||
public abstract class GraphicsBindingsBase : LegacyBindingsBase
|
||||
{
|
||||
internal IntPtr[] _EntryPointsInstance;
|
||||
internal byte[] _EntryPointNamesInstance;
|
||||
internal int[] _EntryPointNameOffsetsInstance;
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves an unmanaged function pointer to the specified function.
|
||||
/// </summary>
|
||||
/// <param name="funcname">
|
||||
/// A <see cref="System.String"/> that defines the name of the function.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A <see cref="IntPtr"/> that contains the address of funcname or IntPtr.Zero,
|
||||
/// if the function is not supported by the drivers.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// Note: some drivers are known to return non-zero values for unsupported functions.
|
||||
/// Typical values include 1 and 2 - inheritors are advised to check for and ignore these
|
||||
/// values.
|
||||
/// </remarks>
|
||||
public override IntPtr GetAddress(string funcname)
|
||||
{
|
||||
var context = GraphicsContext.CurrentContext as IGraphicsContextInternal;
|
||||
if (context == null)
|
||||
{
|
||||
throw new GraphicsContextMissingException();
|
||||
}
|
||||
return context != null ? context.GetAddress(funcname) : IntPtr.Zero;
|
||||
}
|
||||
|
||||
// Loads all available entry points for the current API.
|
||||
// Note: we prefer IGraphicsContextInternal.GetAddress over
|
||||
// this.GetAddress to improve loading performance (less
|
||||
// validation necessary.)
|
||||
internal override void LoadEntryPoints()
|
||||
{
|
||||
Debug.Print("Loading entry points for {0}", GetType().FullName);
|
||||
|
||||
IGraphicsContext context = GraphicsContext.CurrentContext;
|
||||
if (context == null)
|
||||
{
|
||||
throw new GraphicsContextMissingException();
|
||||
}
|
||||
|
||||
IGraphicsContextInternal context_internal = context as IGraphicsContextInternal;
|
||||
unsafe
|
||||
{
|
||||
fixed (byte* name = _EntryPointNamesInstance)
|
||||
{
|
||||
for (int i = 0; i < _EntryPointsInstance.Length; i++)
|
||||
{
|
||||
_EntryPointsInstance[i] = context_internal.GetAddress(
|
||||
new IntPtr(name + _EntryPointNameOffsetsInstance[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
620
GLWidget/OpenTK/Graphics/GraphicsContext.cs
Normal file
620
GLWidget/OpenTK/Graphics/GraphicsContext.cs
Normal file
|
@ -0,0 +1,620 @@
|
|||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2013 Stefanos Apostolopoulos
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
using OpenTK.Platform;
|
||||
|
||||
namespace OpenTK.Graphics
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents and provides methods to manipulate an OpenGL render context.
|
||||
/// </summary>
|
||||
public sealed class GraphicsContext : IGraphicsContext, IGraphicsContextInternal
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to retrive function pointers by name.
|
||||
/// </summary>
|
||||
/// <param name="function">The function name.</param>
|
||||
/// <returns>A function pointer to <paramref name="function"/>, or <c>IntPtr.Zero</c></returns>
|
||||
public delegate IntPtr GetAddressDelegate(string function);
|
||||
|
||||
/// <summary>
|
||||
/// Used to return the handel of the current OpenGL context.
|
||||
/// </summary>
|
||||
/// <returns>The current OpenGL context, or <c>IntPtr.Zero</c> if no context is on the calling thread.</returns>
|
||||
public delegate ContextHandle GetCurrentContextDelegate();
|
||||
|
||||
private IGraphicsContext implementation; // The actual render context implementation for the underlying platform.
|
||||
private bool disposed;
|
||||
|
||||
// Cache for the context handle. We need this for RemoveContext()
|
||||
// in case the user does not call Dispose(). When this happens,
|
||||
// RemoveContext() is called by the finalizer, in which case
|
||||
// the IGraphicsContext implementation may already be null
|
||||
// (hence we cannot call implementation.Context to retrieve
|
||||
// the handle.)
|
||||
private ContextHandle handle_cached;
|
||||
|
||||
private readonly static object SyncRoot = new object();
|
||||
// Maps OS-specific context handles to GraphicsContext instances.
|
||||
private readonly static Dictionary<ContextHandle, IGraphicsContext> available_contexts =
|
||||
new Dictionary<ContextHandle, IGraphicsContext>();
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new GraphicsContext with the specified GraphicsMode and attaches it to the specified window.
|
||||
/// </summary>
|
||||
/// <param name="mode">The OpenTK.Graphics.GraphicsMode of the GraphicsContext.</param>
|
||||
/// <param name="window">The OpenTK.Platform.IWindowInfo to attach the GraphicsContext to.</param>
|
||||
public GraphicsContext(GraphicsMode mode, IWindowInfo window)
|
||||
: this(mode, window, 1, 0, GraphicsContextFlags.Default)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new GraphicsContext with the specified GraphicsMode, version and flags, and attaches it to the specified window.
|
||||
/// </summary>
|
||||
/// <param name="mode">The OpenTK.Graphics.GraphicsMode of the GraphicsContext.</param>
|
||||
/// <param name="window">The OpenTK.Platform.IWindowInfo to attach the GraphicsContext to.</param>
|
||||
/// <param name="major">The major version of the new GraphicsContext.</param>
|
||||
/// <param name="minor">The minor version of the new GraphicsContext.</param>
|
||||
/// <param name="flags">The GraphicsContextFlags for the GraphicsContext.</param>
|
||||
/// <remarks>
|
||||
/// Different hardware supports different flags, major and minor versions. Invalid parameters will be silently ignored.
|
||||
/// </remarks>
|
||||
public GraphicsContext(GraphicsMode mode, IWindowInfo window, int major, int minor, GraphicsContextFlags flags)
|
||||
: this(mode, window, FindSharedContext(), major, minor, flags)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new GraphicsContext with the specified GraphicsMode, version and flags, and attaches it to the specified window. A dummy context will be created if both
|
||||
/// the handle and the window are null.
|
||||
/// </summary>
|
||||
/// <param name="mode">The OpenTK.Graphics.GraphicsMode of the GraphicsContext.</param>
|
||||
/// <param name="window">The OpenTK.Platform.IWindowInfo to attach the GraphicsContext to.</param>
|
||||
/// <param name="shareContext">The GraphicsContext to share resources with, or null for explicit non-sharing.</param>
|
||||
/// <param name="major">The major version of the new GraphicsContext.</param>
|
||||
/// <param name="minor">The minor version of the new GraphicsContext.</param>
|
||||
/// <param name="flags">The GraphicsContextFlags for the GraphicsContext.</param>
|
||||
/// <remarks>
|
||||
/// Different hardware supports different flags, major and minor versions. Invalid parameters will be silently ignored.
|
||||
/// </remarks>
|
||||
public GraphicsContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, int major, int minor, GraphicsContextFlags flags)
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
bool designMode = false;
|
||||
if (mode == null && window == null)
|
||||
{
|
||||
designMode = true;
|
||||
}
|
||||
else if (mode == null)
|
||||
{
|
||||
throw new ArgumentNullException("mode", "Must be a valid GraphicsMode.");
|
||||
}
|
||||
else if (window == null)
|
||||
{
|
||||
throw new ArgumentNullException("window", "Must point to a valid window.");
|
||||
}
|
||||
|
||||
// Silently ignore invalid major and minor versions.
|
||||
if (major <= 0)
|
||||
{
|
||||
major = 1;
|
||||
}
|
||||
if (minor < 0)
|
||||
{
|
||||
minor = 0;
|
||||
}
|
||||
|
||||
// Angle needs an embedded context
|
||||
const GraphicsContextFlags useAngleFlag = GraphicsContextFlags.Angle
|
||||
| GraphicsContextFlags.AngleD3D9
|
||||
| GraphicsContextFlags.AngleD3D11
|
||||
| GraphicsContextFlags.AngleOpenGL;
|
||||
var useAngle = false;
|
||||
if ((flags & useAngleFlag) != 0)
|
||||
{
|
||||
flags |= GraphicsContextFlags.Embedded;
|
||||
useAngle = true;
|
||||
}
|
||||
|
||||
Debug.Print("Creating GraphicsContext.");
|
||||
try
|
||||
{
|
||||
Debug.Indent();
|
||||
Debug.Print("GraphicsMode: {0}", mode);
|
||||
Debug.Print("IWindowInfo: {0}", window);
|
||||
Debug.Print("GraphicsContextFlags: {0}", flags);
|
||||
Debug.Print("Requested version: {0}.{1}", major, minor);
|
||||
|
||||
// Todo: Add a DummyFactory implementing IPlatformFactory.
|
||||
if (designMode)
|
||||
{
|
||||
implementation = new Platform.Dummy.DummyGLContext();
|
||||
}
|
||||
else
|
||||
{
|
||||
IPlatformFactory factory = null;
|
||||
switch ((flags & GraphicsContextFlags.Embedded) == GraphicsContextFlags.Embedded)
|
||||
{
|
||||
case false:
|
||||
factory = Factory.Default;
|
||||
break;
|
||||
case true:
|
||||
factory = useAngle ? Factory.Angle : Factory.Embedded;
|
||||
break;
|
||||
}
|
||||
|
||||
// Note: this approach does not allow us to mix native and EGL contexts in the same process.
|
||||
// This should not be a problem, as this use-case is not interesting for regular applications.
|
||||
// Note 2: some platforms may not support a direct way of getting the current context
|
||||
// (this happens e.g. with DummyGLContext). In that case, we use a slow fallback which
|
||||
// iterates through all known contexts and checks if any is current (check GetCurrentContext
|
||||
// declaration).
|
||||
if (GetCurrentContext == null)
|
||||
{
|
||||
GetCurrentContext = factory.CreateGetCurrentGraphicsContext();
|
||||
}
|
||||
|
||||
implementation = factory.CreateGLContext(mode, window, shareContext, DirectRendering, major, minor, flags);
|
||||
handle_cached = ((IGraphicsContextInternal)implementation).Context;
|
||||
factory.RegisterResource(this);
|
||||
}
|
||||
|
||||
AddContext(this);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Debug.Unindent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="OpenTK.Graphics.GraphicsContext"/> class using
|
||||
/// an external context handle that was created by a third-party library.
|
||||
/// </summary>
|
||||
/// <param name="handle">
|
||||
/// A valid, unique handle for an external OpenGL context, or <c>ContextHandle.Zero</c> to use the current context.
|
||||
/// It is an error to specify a handle that has been created through OpenTK or that has been passed to OpenTK before.
|
||||
/// </param>
|
||||
/// <param name="getAddress">
|
||||
/// A <c>GetAddressDelegate</c> instance that accepts the name of an OpenGL function and returns
|
||||
/// a valid function pointer, or <c>IntPtr.Zero</c> if that function is not supported. This delegate should be
|
||||
/// implemented using the same toolkit that created the OpenGL context (i.e. if the context was created with
|
||||
/// SDL_GL_CreateContext(), then this delegate should use SDL_GL_GetProcAddress() to retrieve function
|
||||
/// pointers.)
|
||||
/// </param>
|
||||
/// <param name="getCurrent">
|
||||
/// A <c>GetCurrentContextDelegate</c> instance that returns the handle of the current OpenGL context,
|
||||
/// or <c>IntPtr.Zero</c> if no context is current on the calling thread. This delegate should be implemented
|
||||
/// using the same toolkit that created the OpenGL context (i.e. if the context was created with
|
||||
/// SDL_GL_CreateContext(), then this delegate should use SDL_GL_GetCurrentContext() to retrieve
|
||||
/// the current context.)
|
||||
/// </param>
|
||||
public GraphicsContext(ContextHandle handle, GetAddressDelegate getAddress, GetCurrentContextDelegate getCurrent)
|
||||
{
|
||||
if (getAddress == null || getCurrent == null)
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
lock (SyncRoot)
|
||||
{
|
||||
// Replace a zero-handle by the current context, if any
|
||||
if (handle == ContextHandle.Zero)
|
||||
{
|
||||
handle = getCurrent();
|
||||
}
|
||||
|
||||
// Make sure this handle corresponds to a valid, unique OpenGL context
|
||||
if (handle == ContextHandle.Zero)
|
||||
{
|
||||
throw new GraphicsContextMissingException();
|
||||
}
|
||||
else if (available_contexts.ContainsKey(handle))
|
||||
{
|
||||
throw new InvalidOperationException("Context handle has already been added");
|
||||
}
|
||||
|
||||
// We have a valid handle for an external OpenGL context, wrap it into a
|
||||
// DummyGLContext instance.
|
||||
implementation = new Platform.Dummy.DummyGLContext(handle, getAddress);
|
||||
GetCurrentContext = getCurrent ?? GetCurrentContext;
|
||||
AddContext(this);
|
||||
}
|
||||
implementation.LoadAll();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new GraphicsContext from a pre-existing context created outside of OpenTK. A dummy context will be created if both
|
||||
/// the handle and the window are null.
|
||||
/// </summary>
|
||||
/// <param name="handle">The handle of the existing context. This must be a valid, unique handle that is not known to OpenTK.</param>
|
||||
/// <param name="window">This parameter is reserved.</param>
|
||||
public GraphicsContext(ContextHandle handle, IWindowInfo window)
|
||||
: this(handle, window, null, 1, 0, GraphicsContextFlags.Default)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new GraphicsContext from a pre-existing context created outside of OpenTK.
|
||||
/// </summary>
|
||||
/// <param name="handle">The handle of the existing context. This must be a valid, unique handle that is not known to OpenTK.</param>
|
||||
/// <param name="window">This parameter is reserved.</param>
|
||||
/// <param name="shareContext">This parameter is reserved.</param>
|
||||
/// <param name="major">This parameter is reserved.</param>
|
||||
/// <param name="minor">This parameter is reserved.</param>
|
||||
/// <param name="flags">This parameter is reserved..</param>
|
||||
public GraphicsContext(ContextHandle handle, IWindowInfo window, IGraphicsContext shareContext, int major, int minor, GraphicsContextFlags flags)
|
||||
: this(handle, Platform.Utilities.CreateGetAddress(), Factory.Default.CreateGetCurrentGraphicsContext())
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="System.String"/> representing this instance.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="System.String"/> that contains a string representation of this instance.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return (this as IGraphicsContextInternal).Context.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the hash code for this instance.
|
||||
/// </summary>
|
||||
/// <returns>A System.Int32 with the hash code of this instance.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return (this as IGraphicsContextInternal).Context.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two instances.
|
||||
/// </summary>
|
||||
/// <param name="obj">The instance to compare to.</param>
|
||||
/// <returns>True, if obj is equal to this instance; false otherwise.</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return (obj is GraphicsContext) &&
|
||||
(this as IGraphicsContextInternal).Context == (obj as IGraphicsContextInternal).Context;
|
||||
}
|
||||
|
||||
private static void AddContext(IGraphicsContextInternal context)
|
||||
{
|
||||
ContextHandle ctx = context.Context;
|
||||
if (!available_contexts.ContainsKey(ctx))
|
||||
{
|
||||
available_contexts.Add(ctx, (IGraphicsContext)context);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Print("A GraphicsContext with handle {0} already exists.", ctx);
|
||||
Debug.Print("Did you forget to call Dispose()?");
|
||||
available_contexts[ctx] = (IGraphicsContext)context;
|
||||
}
|
||||
}
|
||||
|
||||
private static void RemoveContext(IGraphicsContextInternal context)
|
||||
{
|
||||
ContextHandle ctx = context.Context;
|
||||
if (available_contexts.ContainsKey(ctx))
|
||||
{
|
||||
available_contexts.Remove(ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Print("Tried to remove non-existent GraphicsContext handle {0}. Call Dispose() to avoid this error.", ctx);
|
||||
}
|
||||
}
|
||||
|
||||
private static IGraphicsContext FindSharedContext()
|
||||
{
|
||||
if (GraphicsContext.ShareContexts)
|
||||
{
|
||||
// A small hack to create a shared context with the first available context.
|
||||
foreach (IGraphicsContext target in GraphicsContext.available_contexts.Values)
|
||||
{
|
||||
// Fix for bug 1874: if a GraphicsContext gets finalized
|
||||
// (but not disposed), it won't be removed from available_contexts
|
||||
// making this return null even if another valid context exists.
|
||||
// The workaround is to simply ignore null targets.
|
||||
if (target != null)
|
||||
{
|
||||
return target;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a GraphicsContext exists in the calling thread and throws a GraphicsContextMissingException if it doesn't.
|
||||
/// </summary>
|
||||
/// <exception cref="GraphicsContextMissingException">Generated when no GraphicsContext is current in the calling thread.</exception>
|
||||
public static void Assert()
|
||||
{
|
||||
if (GraphicsContext.CurrentContext == null)
|
||||
{
|
||||
throw new GraphicsContextMissingException();
|
||||
}
|
||||
}
|
||||
|
||||
internal static GetCurrentContextDelegate GetCurrentContext;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the handle of the current GraphicsContext in the calling thread.
|
||||
/// </summary>
|
||||
public static ContextHandle CurrentContextHandle
|
||||
{
|
||||
get { return GetCurrentContext(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the GraphicsContext that is current in the calling thread.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note: this property will not function correctly when both desktop and EGL contexts are
|
||||
/// available in the same process. This scenario is very unlikely to appear in practice.
|
||||
/// </remarks>
|
||||
public static IGraphicsContext CurrentContext
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
if (available_contexts.Count > 0)
|
||||
{
|
||||
ContextHandle handle = CurrentContextHandle;
|
||||
if (handle.Handle != IntPtr.Zero)
|
||||
{
|
||||
return (IGraphicsContext)available_contexts[handle];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets or sets a System.Boolean, indicating whether GraphicsContext resources are shared</summary>
|
||||
/// <remarks>
|
||||
/// <para>If ShareContexts is true, new GLContexts will share resources. If this value is
|
||||
/// false, new GLContexts will not share resources.</para>
|
||||
/// <para>Changing this value will not affect already created GLContexts.</para>
|
||||
/// </remarks>
|
||||
public static bool ShareContexts { get; set; } = true;
|
||||
|
||||
/// <summary>Gets or sets a System.Boolean, indicating whether GraphicsContexts will perform direct rendering.</summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// If DirectRendering is true, new contexts will be constructed with direct rendering capabilities, if possible.
|
||||
/// If DirectRendering is false, new contexts will be constructed with indirect rendering capabilities.
|
||||
/// </para>
|
||||
/// <para>This property does not affect existing GraphicsContexts, unless they are recreated.</para>
|
||||
/// <para>
|
||||
/// This property is ignored on Operating Systems without support for indirect rendering, like Windows and OS X.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public static bool DirectRendering { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a System.Boolean, indicating whether automatic error checking should be performed.
|
||||
/// Influences the debug version of OpenTK.dll, only.
|
||||
/// </summary>
|
||||
/// <remarks>Automatic error checking will clear the OpenGL error state. Set CheckErrors to false if you use
|
||||
/// the OpenGL error state in your code flow (e.g. for checking supported texture formats).</remarks>
|
||||
public bool ErrorChecking { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Swaps buffers on a context. This presents the rendered scene to the user.
|
||||
/// </summary>
|
||||
public void SwapBuffers()
|
||||
{
|
||||
implementation.SwapBuffers();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Makes the GraphicsContext the current rendering target.
|
||||
/// </summary>
|
||||
/// <param name="window">A valid <see cref="OpenTK.Platform.IWindowInfo" /> structure.</param>
|
||||
/// <remarks>
|
||||
/// You can use this method to bind the GraphicsContext to a different window than the one it was created from.
|
||||
/// </remarks>
|
||||
public void MakeCurrent(IWindowInfo window)
|
||||
{
|
||||
implementation.MakeCurrent(window);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="System.Boolean"/> indicating whether this instance is current in the calling thread.
|
||||
/// </summary>
|
||||
public bool IsCurrent
|
||||
{
|
||||
get { return implementation.IsCurrent; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="System.Boolean"/> indicating whether this instance has been disposed.
|
||||
/// It is an error to access any instance methods if this property returns true.
|
||||
/// </summary>
|
||||
public bool IsDisposed
|
||||
{
|
||||
get { return disposed && implementation.IsDisposed; }
|
||||
private set { disposed = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a positive integer in the range [1, n), indicating the number of
|
||||
/// <see cref="DisplayDevice"/> refreshes between consecutive
|
||||
/// <see cref="SwapBuffers()"/> calls. The maximum value for n is
|
||||
/// implementation-dependent. The default value is 1.
|
||||
/// Invalid values will be clamped to the valid range.
|
||||
/// </summary>
|
||||
public int SwapInterval
|
||||
{
|
||||
get { return implementation.SwapInterval; }
|
||||
set { implementation.SwapInterval = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the graphics context. This must be called when the render target
|
||||
/// is resized for proper behavior on Mac OS X.
|
||||
/// </summary>
|
||||
/// <param name="window"></param>
|
||||
public void Update(IWindowInfo window)
|
||||
{
|
||||
implementation.Update(window);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads all OpenGL entry points.
|
||||
/// </summary>
|
||||
/// <exception cref="OpenTK.Graphics.GraphicsContextException">
|
||||
/// Occurs when this instance is not current on the calling thread.
|
||||
/// </exception>
|
||||
public void LoadAll()
|
||||
{
|
||||
if (GraphicsContext.CurrentContext != this)
|
||||
{
|
||||
throw new GraphicsContextException();
|
||||
}
|
||||
|
||||
implementation.LoadAll();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the platform-specific implementation of this IGraphicsContext.
|
||||
/// </summary>
|
||||
IGraphicsContext IGraphicsContextInternal.Implementation
|
||||
{
|
||||
get { return implementation; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a handle to the OpenGL rendering context.
|
||||
/// </summary>
|
||||
ContextHandle IGraphicsContextInternal.Context
|
||||
{
|
||||
get
|
||||
{
|
||||
if (implementation != null)
|
||||
{
|
||||
handle_cached = ((IGraphicsContextInternal)implementation).Context;
|
||||
}
|
||||
return handle_cached;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the GraphicsMode of the context.
|
||||
/// </summary>
|
||||
public GraphicsMode GraphicsMode
|
||||
{
|
||||
get { return (implementation as IGraphicsContext).GraphicsMode; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the implementation-defined address of an OpenGL function.
|
||||
/// </summary>
|
||||
/// <param name="function">The name of the OpenGL function (e.g. "glGetString")</param>
|
||||
/// <returns>
|
||||
/// A pointer to the specified function or an invalid pointer if the function is not
|
||||
/// available in the current OpenGL context. The return value and calling convention
|
||||
/// depends on the underlying platform.
|
||||
/// </returns>
|
||||
IntPtr IGraphicsContextInternal.GetAddress(string function)
|
||||
{
|
||||
IntPtr name = System.Runtime.InteropServices.Marshal.StringToHGlobalAnsi(function);
|
||||
IntPtr address = (implementation as IGraphicsContextInternal).GetAddress(name);
|
||||
System.Runtime.InteropServices.Marshal.FreeHGlobal(name);
|
||||
return address;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the implementation-defined address of an OpenGL function.
|
||||
/// </summary>
|
||||
/// <param name="function">
|
||||
/// A pointer to a null-terminated buffer
|
||||
/// containing the name of the OpenGL function.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A pointer to the specified function or an invalid pointer if the function is not
|
||||
/// available in the current OpenGL context. The return value and calling convention
|
||||
/// depends on the underlying platform.
|
||||
/// </returns>
|
||||
IntPtr IGraphicsContextInternal.GetAddress(IntPtr function)
|
||||
{
|
||||
return (implementation as IGraphicsContextInternal).GetAddress(function);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes of the GraphicsContext.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
this.Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
private void Dispose(bool manual)
|
||||
{
|
||||
if (!IsDisposed)
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
RemoveContext(this);
|
||||
}
|
||||
|
||||
// Note: we cannot dispose the implementation
|
||||
// from a different thread. See wglDeleteContext.
|
||||
// This is also known to crash GLX implementations.
|
||||
if (manual)
|
||||
{
|
||||
Debug.Print("Disposing context {0}.", (this as IGraphicsContextInternal).Context.ToString());
|
||||
if (implementation != null)
|
||||
{
|
||||
implementation.Dispose();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.WriteLine("GraphicsContext leaked, did you forget to call Dispose()?");
|
||||
}
|
||||
IsDisposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Marks this context as deleted, but does not actually release unmanaged resources
|
||||
/// due to the threading requirements of OpenGL. Use <see cref="GraphicsContext.Dispose()"/>
|
||||
/// instead.
|
||||
/// </summary>
|
||||
~GraphicsContext()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
}
|
||||
}
|
132
GLWidget/OpenTK/Graphics/GraphicsContextBase.cs
Normal file
132
GLWidget/OpenTK/Graphics/GraphicsContextBase.cs
Normal file
|
@ -0,0 +1,132 @@
|
|||
//
|
||||
// GraphicsContextBase.cs
|
||||
//
|
||||
// Author:
|
||||
// Stefanos A. <stapostol@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2006-2014 Stefanos Apostolopoulos
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using OpenTK.Platform;
|
||||
|
||||
namespace OpenTK.Graphics
|
||||
{
|
||||
// Provides the foundation for all IGraphicsContext implementations.
|
||||
internal abstract class GraphicsContextBase : IGraphicsContext, IGraphicsContextInternal, IEquatable<IGraphicsContextInternal>
|
||||
{
|
||||
protected ContextHandle Handle;
|
||||
protected GraphicsMode Mode;
|
||||
|
||||
public abstract void SwapBuffers();
|
||||
|
||||
public abstract void MakeCurrent(IWindowInfo window);
|
||||
|
||||
public abstract bool IsCurrent { get; }
|
||||
|
||||
public bool IsDisposed { get; protected set; }
|
||||
|
||||
public bool VSync
|
||||
{
|
||||
get { return SwapInterval > 0; }
|
||||
set
|
||||
{
|
||||
if (value && SwapInterval <= 0)
|
||||
{
|
||||
SwapInterval = 1;
|
||||
}
|
||||
else if (!value && SwapInterval > 0)
|
||||
{
|
||||
SwapInterval = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract int SwapInterval { get; set; }
|
||||
|
||||
public virtual void Update(IWindowInfo window) { }
|
||||
|
||||
public GraphicsMode GraphicsMode { get { return Mode; } }
|
||||
|
||||
public bool ErrorChecking
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
set { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
public IGraphicsContext Implementation { get { return this; } }
|
||||
|
||||
public abstract void LoadAll();
|
||||
|
||||
public ContextHandle Context { get { return Handle; } }
|
||||
|
||||
// This function is no longer used.
|
||||
// The GraphicsContext facade will
|
||||
// always call the IntPtr overload.
|
||||
public IntPtr GetAddress(string function)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public abstract IntPtr GetAddress(IntPtr function);
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected abstract void Dispose(bool disposing);
|
||||
|
||||
#if DEBUG
|
||||
~GraphicsContextBase()
|
||||
{
|
||||
Dispose(false);
|
||||
Debug.Print("[Warning] {0}:{1} leaked. Did you forget to call Dispose()?",
|
||||
GetType().FullName, Handle);
|
||||
}
|
||||
#endif
|
||||
|
||||
public bool Equals(IGraphicsContextInternal other)
|
||||
{
|
||||
return Context.Equals(other.Context);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("[{0}: IsCurrent={1}, IsDisposed={2}, VSync={3}, SwapInterval={4}, GraphicsMode={5}, Context={6}]",
|
||||
GetType().Name, IsCurrent, IsDisposed, VSync, SwapInterval, GraphicsMode, Context);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Handle.GetHashCode();
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return
|
||||
obj is IGraphicsContextInternal &&
|
||||
Equals((IGraphicsContextInternal)obj);
|
||||
}
|
||||
}
|
||||
}
|
19
GLWidget/OpenTK/Graphics/GraphicsContextException.cs
Normal file
19
GLWidget/OpenTK/Graphics/GraphicsContextException.cs
Normal file
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
|
||||
namespace OpenTK.Graphics
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents errors related to a GraphicsContext.
|
||||
/// </summary>
|
||||
public class GraphicsContextException : Exception
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructs a new GraphicsContextException.
|
||||
/// </summary>
|
||||
public GraphicsContextException() : base() { }
|
||||
/// <summary>
|
||||
/// Constructs a new GraphicsContextException with the given error message.
|
||||
/// </summary>
|
||||
public GraphicsContextException(string message) : base(message) { }
|
||||
}
|
||||
}
|
81
GLWidget/OpenTK/Graphics/GraphicsContextFlags.cs
Normal file
81
GLWidget/OpenTK/Graphics/GraphicsContextFlags.cs
Normal file
|
@ -0,0 +1,81 @@
|
|||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2008 the Open Toolkit library, except where noted.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
|
||||
namespace OpenTK.Graphics
|
||||
{
|
||||
/// <summary>
|
||||
/// Enumerates various flags that affect the creation of new GraphicsContexts.
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum GraphicsContextFlags
|
||||
{
|
||||
/// <summary>
|
||||
/// The default value of the GraphicsContextFlags enumeration.
|
||||
/// </summary>
|
||||
Default = 0x0000,
|
||||
/// <summary>
|
||||
/// Indicates that this is a debug GraphicsContext. Debug contexts may provide
|
||||
/// additional debugging information at the cost of performance.
|
||||
/// </summary>
|
||||
/// <remarks></remarks>
|
||||
Debug = 0x0001,
|
||||
/// <summary>
|
||||
/// Indicates that this is a forward compatible GraphicsContext. Forward-compatible contexts
|
||||
/// do not support functionality marked as deprecated in the current GraphicsContextVersion.
|
||||
/// </summary>
|
||||
/// <remarks>Forward-compatible contexts are defined only for OpenGL versions 3.0 and later.</remarks>
|
||||
ForwardCompatible = 0x0002,
|
||||
/// <summary>
|
||||
/// Indicates that this GraphicsContext is targeting OpenGL|ES.
|
||||
/// </summary>
|
||||
Embedded = 0x0004,
|
||||
/// <summary>
|
||||
/// Indicates that this GraphicsContext is intended for offscreen rendering.
|
||||
/// </summary>
|
||||
Offscreen = 0x0008,
|
||||
/// <summary>
|
||||
/// Indicates that this GraphicsContext is targeting OpenGL|ES via Angle
|
||||
/// and that angle-specific extensions are available.
|
||||
/// </summary>
|
||||
Angle = 0x0010,
|
||||
/// <summary>
|
||||
/// Indicates that this GraphicsContext is targeting OpenGL|ES via Angle
|
||||
/// and uses Direct3D9 as rendering backend.
|
||||
/// </summary>
|
||||
AngleD3D9 = 0x0020,
|
||||
/// <summary>
|
||||
/// Indicates that this GraphicsContext is targeting OpenGL|ES via Angle
|
||||
/// and uses Direct3D11 as rendering backend.
|
||||
/// </summary>
|
||||
AngleD3D11 = 0x0040,
|
||||
/// <summary>
|
||||
/// Indicates that this GraphicsContext is targeting OpenGL|ES via Angle
|
||||
/// and uses OpenGL as rendering backend.
|
||||
/// </summary>
|
||||
AngleOpenGL = 0x0080,
|
||||
}
|
||||
}
|
20
GLWidget/OpenTK/Graphics/GraphicsContextMissingException.cs
Normal file
20
GLWidget/OpenTK/Graphics/GraphicsContextMissingException.cs
Normal file
|
@ -0,0 +1,20 @@
|
|||
using System;
|
||||
|
||||
namespace OpenTK.Graphics
|
||||
{
|
||||
/// <summary>
|
||||
/// Thrown when an operation that required GraphicsContext is performed, when no
|
||||
/// GraphicsContext is current in the calling thread.
|
||||
/// </summary>
|
||||
public class GraphicsContextMissingException : GraphicsContextException
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructs a new GraphicsContextMissingException.
|
||||
/// </summary>
|
||||
public GraphicsContextMissingException()
|
||||
: base(String.Format(
|
||||
"No context is current in the calling thread (ThreadId: {0}).",
|
||||
System.Threading.Thread.CurrentThread.ManagedThreadId))
|
||||
{ }
|
||||
}
|
||||
}
|
63
GLWidget/OpenTK/Graphics/GraphicsContextVersion.cs
Normal file
63
GLWidget/OpenTK/Graphics/GraphicsContextVersion.cs
Normal file
|
@ -0,0 +1,63 @@
|
|||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2008 the Open Toolkit library, except where noted.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
|
||||
namespace OpenTK.Graphics
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the version information of a GraphicsContext.
|
||||
/// </summary>
|
||||
public sealed class GraphicsContextVersion
|
||||
{
|
||||
internal GraphicsContextVersion(int minor, int major, string vendor, string renderer)
|
||||
{
|
||||
Minor = minor;
|
||||
Major = major;
|
||||
Vendor = vendor;
|
||||
Renderer = renderer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a System.Int32 indicating the minor version of a GraphicsContext instance.
|
||||
/// </summary>
|
||||
public int Minor { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a System.Int32 indicating the major version of a GraphicsContext instance.
|
||||
/// </summary>
|
||||
public int Major { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a System.String indicating the vendor of a GraphicsContext instance.
|
||||
/// </summary>
|
||||
public string Vendor { get; private set; } = String.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a System.String indicating the renderer of a GraphicsContext instance.
|
||||
/// </summary>
|
||||
public string Renderer { get; private set; } = String.Empty;
|
||||
}
|
||||
}
|
17
GLWidget/OpenTK/Graphics/GraphicsErrorException.cs
Normal file
17
GLWidget/OpenTK/Graphics/GraphicsErrorException.cs
Normal file
|
@ -0,0 +1,17 @@
|
|||
namespace OpenTK.Graphics
|
||||
{
|
||||
/// <summary>
|
||||
/// Identifies a specific OpenGL or OpenGL|ES error. Such exceptions are only thrown
|
||||
/// when OpenGL or OpenGL|ES automatic error checking is enabled -
|
||||
/// <see cref="GraphicsContext.ErrorChecking"/> property.
|
||||
/// Important: Do *not* catch this exception. Rather, fix the underlying issue that caused the error.
|
||||
/// </summary>
|
||||
public class GraphicsErrorException : GraphicsException
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructs a new GraphicsErrorException instance with the specified error message.
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
public GraphicsErrorException(string message) : base(message) { }
|
||||
}
|
||||
}
|
20
GLWidget/OpenTK/Graphics/GraphicsExceptions.cs
Normal file
20
GLWidget/OpenTK/Graphics/GraphicsExceptions.cs
Normal file
|
@ -0,0 +1,20 @@
|
|||
/* Licensed under the MIT/X11 license.
|
||||
* Copyright (c) 2006-2008 the OpenTK team.
|
||||
* This notice may not be removed.
|
||||
* See license.txt for licensing detailed licensing details.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace OpenTK
|
||||
{
|
||||
/// <summary>Represents errors related to Graphics operations.</summary>
|
||||
public class GraphicsException : Exception
|
||||
{
|
||||
/// <summary>Constructs a new GraphicsException.</summary>
|
||||
public GraphicsException() : base() { }
|
||||
/// <summary>Constructs a new GraphicsException with the specified excpetion message.</summary>
|
||||
/// <param name="message"></param>
|
||||
public GraphicsException(string message) : base(message) { }
|
||||
}
|
||||
}
|
239
GLWidget/OpenTK/Graphics/GraphicsMode.cs
Normal file
239
GLWidget/OpenTK/Graphics/GraphicsMode.cs
Normal file
|
@ -0,0 +1,239 @@
|
|||
/* Licensed under the MIT/X11 license.
|
||||
* Copyright (c) 2006-2008 the OpenTK Team.
|
||||
* This notice may not be removed from any source distribution.
|
||||
* See license.txt for licensing detailed licensing details.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using OpenTK.Core;
|
||||
|
||||
namespace OpenTK.Graphics
|
||||
{
|
||||
/// <summary>Defines the format for graphics operations.</summary>
|
||||
public class GraphicsMode : IEquatable<GraphicsMode>
|
||||
{
|
||||
private int samples;
|
||||
|
||||
private static GraphicsMode defaultMode;
|
||||
private static readonly object SyncRoot = new object();
|
||||
|
||||
// Disable BeforeFieldInit
|
||||
static GraphicsMode() { }
|
||||
|
||||
internal GraphicsMode(GraphicsMode mode)
|
||||
: this(mode.ColorFormat, mode.Depth, mode.Stencil, mode.Samples, mode.AccumulatorFormat, mode.Buffers, mode.Stereo) { }
|
||||
|
||||
internal GraphicsMode(IntPtr? index, ColorFormat color, int depth, int stencil, int samples, ColorFormat accum,
|
||||
int buffers, bool stereo)
|
||||
{
|
||||
if (depth < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("depth", "Must be greater than, or equal to zero.");
|
||||
}
|
||||
if (stencil < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("stencil", "Must be greater than, or equal to zero.");
|
||||
}
|
||||
if (buffers < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("buffers", "Must be greater than, or equal to zero.");
|
||||
}
|
||||
if (samples < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("samples", "Must be greater than, or equal to zero.");
|
||||
}
|
||||
|
||||
this.Index = index;
|
||||
this.ColorFormat = color;
|
||||
this.Depth = depth;
|
||||
this.Stencil = stencil;
|
||||
this.Samples = samples;
|
||||
this.AccumulatorFormat = accum;
|
||||
this.Buffers = buffers;
|
||||
this.Stereo = stereo;
|
||||
}
|
||||
|
||||
/// <summary>Constructs a new GraphicsMode with sensible default parameters.</summary>
|
||||
public GraphicsMode()
|
||||
: this(Default)
|
||||
{ }
|
||||
|
||||
/// <summary>Constructs a new GraphicsMode with the specified parameters.</summary>
|
||||
/// <param name="color">The ColorFormat of the color buffer.</param>
|
||||
public GraphicsMode(ColorFormat color)
|
||||
: this(color, Default.Depth, Default.Stencil, Default.Samples, Default.AccumulatorFormat, Default.Buffers, Default.Stereo)
|
||||
{ }
|
||||
|
||||
/// <summary>Constructs a new GraphicsMode with the specified parameters.</summary>
|
||||
/// <param name="color">The ColorFormat of the color buffer.</param>
|
||||
/// <param name="depth">The number of bits in the depth buffer.</param>
|
||||
public GraphicsMode(ColorFormat color, int depth)
|
||||
: this(color, depth, Default.Stencil, Default.Samples, Default.AccumulatorFormat, Default.Buffers, Default.Stereo)
|
||||
{ }
|
||||
|
||||
/// <summary>Constructs a new GraphicsMode with the specified parameters.</summary>
|
||||
/// <param name="color">The ColorFormat of the color buffer.</param>
|
||||
/// <param name="depth">The number of bits in the depth buffer.</param>
|
||||
/// <param name="stencil">The number of bits in the stencil buffer.</param>
|
||||
public GraphicsMode(ColorFormat color, int depth, int stencil)
|
||||
: this(color, depth, stencil, Default.Samples, Default.AccumulatorFormat, Default.Buffers, Default.Stereo)
|
||||
{ }
|
||||
|
||||
/// <summary>Constructs a new GraphicsMode with the specified parameters.</summary>
|
||||
/// <param name="color">The ColorFormat of the color buffer.</param>
|
||||
/// <param name="depth">The number of bits in the depth buffer.</param>
|
||||
/// <param name="stencil">The number of bits in the stencil buffer.</param>
|
||||
/// <param name="samples">The number of samples for FSAA.</param>
|
||||
public GraphicsMode(ColorFormat color, int depth, int stencil, int samples)
|
||||
: this(color, depth, stencil, samples, Default.AccumulatorFormat, Default.Buffers, Default.Stereo)
|
||||
{ }
|
||||
|
||||
/// <summary>Constructs a new GraphicsMode with the specified parameters.</summary>
|
||||
/// <param name="color">The ColorFormat of the color buffer.</param>
|
||||
/// <param name="depth">The number of bits in the depth buffer.</param>
|
||||
/// <param name="stencil">The number of bits in the stencil buffer.</param>
|
||||
/// <param name="samples">The number of samples for FSAA.</param>
|
||||
/// <param name="accum">The ColorFormat of the accumilliary buffer.</param>
|
||||
public GraphicsMode(ColorFormat color, int depth, int stencil, int samples, ColorFormat accum)
|
||||
: this(color, depth, stencil, samples, accum, Default.Buffers, Default.Stereo)
|
||||
{ }
|
||||
|
||||
/// <summary>Constructs a new GraphicsMode with the specified parameters.</summary>
|
||||
/// <param name="color">The ColorFormat of the color buffer.</param>
|
||||
/// <param name="depth">The number of bits in the depth buffer.</param>
|
||||
/// <param name="stencil">The number of bits in the stencil buffer.</param>
|
||||
/// <param name="samples">The number of samples for FSAA.</param>
|
||||
/// <param name="accum">The ColorFormat of the accumilliary buffer.</param>
|
||||
/// <param name="buffers">The number of render buffers. Typical values include one (single-), two (double-) or three (triple-buffering).</param>
|
||||
public GraphicsMode(ColorFormat color, int depth, int stencil, int samples, ColorFormat accum, int buffers)
|
||||
: this(color, depth, stencil, samples, accum, buffers, Default.Stereo)
|
||||
{ }
|
||||
|
||||
/// <summary>Constructs a new GraphicsMode with the specified parameters.</summary>
|
||||
/// <param name="color">The ColorFormat of the color buffer.</param>
|
||||
/// <param name="depth">The number of bits in the depth buffer.</param>
|
||||
/// <param name="stencil">The number of bits in the stencil buffer.</param>
|
||||
/// <param name="samples">The number of samples for FSAA.</param>
|
||||
/// <param name="accum">The ColorFormat of the accumilliary buffer.</param>
|
||||
/// <param name="stereo">Set to true for a GraphicsMode with stereographic capabilities.</param>
|
||||
/// <param name="buffers">The number of render buffers. Typical values include one (single-), two (double-) or three (triple-buffering).</param>
|
||||
public GraphicsMode(ColorFormat color, int depth, int stencil, int samples, ColorFormat accum, int buffers, bool stereo)
|
||||
: this(null, color, depth, stencil, samples, accum, buffers, stereo) { }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a nullable <see cref="System.IntPtr"/> value, indicating the platform-specific index for this GraphicsMode.
|
||||
/// </summary>
|
||||
public IntPtr? Index { get; set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// Gets an OpenTK.Graphics.ColorFormat that describes the color format for this GraphicsFormat.
|
||||
/// </summary>
|
||||
public ColorFormat ColorFormat { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets an OpenTK.Graphics.ColorFormat that describes the accumulator format for this GraphicsFormat.
|
||||
/// </summary>
|
||||
public ColorFormat AccumulatorFormat { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a System.Int32 that contains the bits per pixel for the depth buffer
|
||||
/// for this GraphicsFormat.
|
||||
/// </summary>
|
||||
public int Depth { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a System.Int32 that contains the bits per pixel for the stencil buffer
|
||||
/// of this GraphicsFormat.
|
||||
/// </summary>
|
||||
public int Stencil { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a System.Int32 that contains the number of FSAA samples per pixel for this GraphicsFormat.
|
||||
/// </summary>
|
||||
public int Samples
|
||||
{
|
||||
get
|
||||
{
|
||||
return samples;
|
||||
}
|
||||
private set
|
||||
{
|
||||
// Clamp antialiasing samples to max 64x
|
||||
// This protects against a potential DOS during
|
||||
// mode selection, when the user requests an
|
||||
// abnormally high AA level.
|
||||
samples = Math.Clamp(value, 0, 64);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a System.Boolean indicating whether this DisplayMode is stereoscopic.
|
||||
/// </summary>
|
||||
public bool Stereo { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a System.Int32 containing the number of buffers associated with this
|
||||
/// DisplayMode.
|
||||
/// </summary>
|
||||
public int Buffers { get; private set; }
|
||||
|
||||
/// <summary>Returns an OpenTK.GraphicsFormat compatible with the underlying platform.</summary>
|
||||
public static GraphicsMode Default
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
if (defaultMode == null)
|
||||
{
|
||||
defaultMode = new GraphicsMode(null, 32, 16, 0, 0, 0, 2, false);
|
||||
Debug.Print("GraphicsMode.Default = {0}", defaultMode.ToString());
|
||||
}
|
||||
return defaultMode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Returns a System.String describing the current GraphicsFormat.</summary>
|
||||
/// <returns>! System.String describing the current GraphicsFormat.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("Index: {0}, Color: {1}, Depth: {2}, Stencil: {3}, Samples: {4}, Accum: {5}, Buffers: {6}, Stereo: {7}",
|
||||
Index, ColorFormat, Depth, Stencil, Samples, AccumulatorFormat, Buffers, Stereo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the hashcode for this instance.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="System.Int32"/> hashcode for this instance.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Index.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether obj is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="obj">An object instance to compare for equality.</param>
|
||||
/// <returns>True, if obj equals this instance; false otherwise.</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is GraphicsMode)
|
||||
{
|
||||
return Equals((GraphicsMode)obj);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether other represents the same mode as this instance.
|
||||
/// </summary>
|
||||
/// <param name="other">The GraphicsMode to compare to.</param>
|
||||
/// <returns>True, if other is equal to this instance; false otherwise.</returns>
|
||||
public bool Equals(GraphicsMode other)
|
||||
{
|
||||
return Index.HasValue && Index == other.Index;
|
||||
}
|
||||
}
|
||||
}
|
67
GLWidget/OpenTK/Graphics/GraphicsModeComparer.cs
Normal file
67
GLWidget/OpenTK/Graphics/GraphicsModeComparer.cs
Normal file
|
@ -0,0 +1,67 @@
|
|||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2010 the Open Toolkit library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace OpenTK.Graphics
|
||||
{
|
||||
internal sealed class GraphicsModeComparer : IComparer<GraphicsMode>
|
||||
{
|
||||
public int Compare(GraphicsMode x, GraphicsMode y)
|
||||
{
|
||||
int result = x.ColorFormat.CompareTo(y.ColorFormat);
|
||||
if (result != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
result = x.Depth.CompareTo(y.Depth);
|
||||
if (result != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
result = x.Stencil.CompareTo(y.Stencil);
|
||||
if (result != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
result = x.Samples.CompareTo(y.Samples);
|
||||
if (result != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
result = x.Stereo.CompareTo(y.Stereo);
|
||||
if (result != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
result = x.Buffers.CompareTo(y.Buffers);
|
||||
if (result != 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return x.AccumulatorFormat.CompareTo(y.AccumulatorFormat);
|
||||
}
|
||||
}
|
||||
}
|
19
GLWidget/OpenTK/Graphics/GraphicsModeException.cs
Normal file
19
GLWidget/OpenTK/Graphics/GraphicsModeException.cs
Normal file
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
|
||||
namespace OpenTK.Graphics
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents errors related to unavailable graphics parameters.
|
||||
/// </summary>
|
||||
public class GraphicsModeException : Exception
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructs a new GraphicsModeException.
|
||||
/// </summary>
|
||||
public GraphicsModeException() : base() { }
|
||||
/// <summary>
|
||||
/// Constructs a new GraphicsModeException with the given error message.
|
||||
/// </summary>
|
||||
public GraphicsModeException(string message) : base(message) { }
|
||||
}
|
||||
}
|
122
GLWidget/OpenTK/Graphics/IGraphicsContext.cs
Normal file
122
GLWidget/OpenTK/Graphics/IGraphicsContext.cs
Normal file
|
@ -0,0 +1,122 @@
|
|||
/* Licensed under the MIT/X11 license.
|
||||
* Copyright (c) 2006-2008 the OpenTK Team.
|
||||
* This notice may not be removed from any source distribution.
|
||||
* See license.txt for licensing detailed licensing details.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using OpenTK.Platform;
|
||||
|
||||
namespace OpenTK.Graphics
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides methods for creating and interacting with an OpenGL context.
|
||||
/// </summary>
|
||||
public interface IGraphicsContext : IDisposable
|
||||
{
|
||||
/// <summary>Swaps buffers, presenting the rendered scene to the user.</summary>
|
||||
void SwapBuffers();
|
||||
|
||||
/// <summary>Makes the GraphicsContext current in the calling thread.</summary>
|
||||
/// <param name="window">An OpenTK.Platform.IWindowInfo structure that points to a valid window.</param>
|
||||
/// <remarks>
|
||||
/// <para>OpenGL commands in one thread, affect the GraphicsContext which is current in that thread.</para>
|
||||
/// <para>It is an error to issue an OpenGL command in a thread without a current GraphicsContext.</para>
|
||||
/// </remarks>
|
||||
void MakeCurrent(IWindowInfo window);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="System.Boolean"/> indicating whether this instance is current in the calling thread.
|
||||
/// </summary>
|
||||
bool IsCurrent { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="System.Boolean"/> indicating whether this instance has been disposed.
|
||||
/// It is an error to access any instance methods if this property returns true.
|
||||
/// </summary>
|
||||
bool IsDisposed { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a positive integer in the range [1, n), indicating the number of
|
||||
/// <see cref="DisplayDevice"/> refreshes between consecutive
|
||||
/// <see cref="SwapBuffers()"/> calls. The maximum value for n is
|
||||
/// implementation-dependent. The default value is 1.
|
||||
/// Invalid values will be clamped to the valid range.
|
||||
/// </summary>
|
||||
int SwapInterval { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Updates the graphics context. This must be called when the region the graphics context
|
||||
/// is drawn to is resized.
|
||||
/// </summary>
|
||||
/// <param name="window"></param>
|
||||
void Update(IWindowInfo window);
|
||||
|
||||
/// <summary>Gets the GraphicsMode of this instance.</summary>
|
||||
GraphicsMode GraphicsMode { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a System.Boolean, indicating whether automatic error checking should be performed.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>It is an error to enable error checking inside a Begin()-End() region.</para>
|
||||
/// <para>This method only affects the debug version of OpenTK.dll.</para>
|
||||
/// </remarks>
|
||||
bool ErrorChecking { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Loads all OpenGL entry points. Requires this instance to be current on the calling thread.
|
||||
/// </summary>
|
||||
void LoadAll();
|
||||
}
|
||||
|
||||
// Functions for internal use by OpenTK.
|
||||
// TODO: RegisterForDisposal/DisposeResources for 0.3.15 (GC & OpenGL)
|
||||
// TODO: Remove or move GetDisplayModes to another class.
|
||||
/// <summary>
|
||||
/// Provides methods to create new GraphicsContexts. Should only be used for extending OpenTK.
|
||||
/// </summary>
|
||||
public interface IGraphicsContextInternal
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the internal implementation of the current instance.
|
||||
/// </summary>
|
||||
IGraphicsContext Implementation { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Loads all OpenGL entry points. Requires this instance to be current on the calling thread.
|
||||
/// </summary>
|
||||
void LoadAll();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a handle to the OpenGL rendering context.
|
||||
/// </summary>
|
||||
ContextHandle Context { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the implementation-defined address of an OpenGL function.
|
||||
/// </summary>
|
||||
/// <param name="function">The name of the OpenGL function (e.g. "glGetString")</param>
|
||||
/// <returns>
|
||||
/// A pointer to the specified function or an invalid pointer if the function is not
|
||||
/// available in the current OpenGL context. The return value and calling convention
|
||||
/// depends on the underlying platform.
|
||||
/// </returns>
|
||||
IntPtr GetAddress(string function);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the implementation-defined address of an OpenGL function.
|
||||
/// </summary>
|
||||
/// <param name="function">
|
||||
/// A pointer to a null-terminated buffer
|
||||
/// containing the name of the OpenGL function.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A pointer to the specified function or an invalid pointer if the function is not
|
||||
/// available in the current OpenGL context. The return value and calling convention
|
||||
/// depends on the underlying platform.
|
||||
/// </returns>
|
||||
/// <remarks><seealso cref="GetAddress(string)"/></remarks>
|
||||
IntPtr GetAddress(IntPtr function);
|
||||
}
|
||||
}
|
16
GLWidget/OpenTK/Graphics/IGraphicsMode.cs
Normal file
16
GLWidget/OpenTK/Graphics/IGraphicsMode.cs
Normal file
|
@ -0,0 +1,16 @@
|
|||
/* Licensed under the MIT/X11 license.
|
||||
* Copyright (c) 2006-2008 the OpenTK Team.
|
||||
* This notice may not be removed from any source distribution.
|
||||
* See license.txt for licensing detailed licensing details.
|
||||
*/
|
||||
|
||||
namespace OpenTK.Graphics
|
||||
{
|
||||
internal interface IGraphicsMode
|
||||
{
|
||||
// Creates a temporary OpenGL context (if necessary) and finds the mode which closest matches
|
||||
// the specified parameters.
|
||||
GraphicsMode SelectGraphicsMode(ColorFormat color, int depth, int stencil, int samples, ColorFormat accum, int buffers,
|
||||
bool stereo);
|
||||
}
|
||||
}
|
80
GLWidget/OpenTK/Platform/DesktopGraphicsContext.cs
Normal file
80
GLWidget/OpenTK/Platform/DesktopGraphicsContext.cs
Normal file
|
@ -0,0 +1,80 @@
|
|||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2009 the Open Toolkit library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace OpenTK.Platform
|
||||
{
|
||||
// Provides the foundation for all desktop IGraphicsContext implementations.
|
||||
internal abstract class DesktopGraphicsContext : GraphicsContextBase
|
||||
{
|
||||
public override void LoadAll()
|
||||
{
|
||||
// Modern unices can use EGL to create
|
||||
// both GL and ES contexts, so we need
|
||||
// to load all entry points. This is
|
||||
// especially true on KMS, Wayland and Mir.
|
||||
|
||||
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");
|
||||
|
||||
Debug.Print("Bindings loaded in {0} ms.", time.Elapsed.TotalMilliseconds);
|
||||
}
|
||||
}
|
||||
}
|
227
GLWidget/OpenTK/Platform/DeviceCollection.cs
Normal file
227
GLWidget/OpenTK/Platform/DeviceCollection.cs
Normal file
|
@ -0,0 +1,227 @@
|
|||
//
|
||||
// DeviceCollection.cs
|
||||
//
|
||||
// Author:
|
||||
// Stefanos A. <stapostol@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2006-2014
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace OpenTK.Platform
|
||||
{
|
||||
// Holds a collection of hardware devices with an associated id.
|
||||
// Note: 'id' refers to a unique hardware-specific device identifier.
|
||||
// Note: 'index' refers to the offset of the device in the Devices array.
|
||||
// Indices are allocated sequentially as devices are added to the system.
|
||||
// If a device is removed, its index will be reused for the next device
|
||||
// that is added.
|
||||
internal class DeviceCollection<T> : IEnumerable<T>
|
||||
{
|
||||
internal struct Enumerator : IEnumerator<T>
|
||||
{
|
||||
private int Index;
|
||||
private DeviceCollection<T> Collection;
|
||||
|
||||
internal Enumerator(DeviceCollection<T> collection)
|
||||
{
|
||||
Collection = collection;
|
||||
Index = -1;
|
||||
Current = default(T);
|
||||
}
|
||||
|
||||
public T Current { get; private set; }
|
||||
|
||||
object IEnumerator.Current
|
||||
{
|
||||
get
|
||||
{
|
||||
return Current;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
do
|
||||
{
|
||||
++Index;
|
||||
if (Index < Collection.Devices.Count)
|
||||
{
|
||||
Current = Collection.Devices[Index];
|
||||
}
|
||||
} while (Index < Collection.Devices.Count && Collection.Devices[Index] == null);
|
||||
|
||||
return Index < Collection.Devices.Count;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
Index = -1;
|
||||
Current = default(T);
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Dictionary<long, int> Map = new Dictionary<long, int>();
|
||||
private readonly List<T> Devices = new List<T>();
|
||||
|
||||
IEnumerator<T> IEnumerable<T>.GetEnumerator()
|
||||
{
|
||||
return new Enumerator(this);
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return new Enumerator(this);
|
||||
}
|
||||
|
||||
// This avoids boxing when using foreach loops
|
||||
public Enumerator GetEnumerator()
|
||||
{
|
||||
return new Enumerator(this);
|
||||
}
|
||||
|
||||
public T this[int index]
|
||||
{
|
||||
get { return FromIndex(index); }
|
||||
}
|
||||
|
||||
/// \internal
|
||||
/// <summary>
|
||||
/// Adds or replaces a device based on its hardware id.
|
||||
/// A zero-based device index will be generated automatically
|
||||
/// for the first available device slot.
|
||||
/// </summary>
|
||||
/// <param name="id">The hardware id for the device.</param>
|
||||
/// <param name="device">The device instance.</param>
|
||||
public void Add(long id, T device)
|
||||
{
|
||||
if (!Map.ContainsKey(id))
|
||||
{
|
||||
int index = GetIndex();
|
||||
Map.Add(id, index);
|
||||
}
|
||||
|
||||
Devices[Map[id]] = device;
|
||||
}
|
||||
|
||||
public void Remove(long id)
|
||||
{
|
||||
if (!TryRemove(id))
|
||||
{
|
||||
Debug.Print("Invalid DeviceCollection<{0}> id: {1}", typeof(T).FullName, id);
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryRemove(long id)
|
||||
{
|
||||
if (!Map.ContainsKey(id))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Devices[Map[id]] = default(T);
|
||||
Map.Remove(id);
|
||||
return true;
|
||||
}
|
||||
|
||||
public T FromIndex(int index)
|
||||
{
|
||||
if (index >= 0 && index < Devices.Count)
|
||||
{
|
||||
return Devices[index];
|
||||
}
|
||||
else
|
||||
{
|
||||
return default(T);
|
||||
}
|
||||
}
|
||||
|
||||
public bool FromIndex(int index, out T device)
|
||||
{
|
||||
if (index >= 0 && index < Devices.Count)
|
||||
{
|
||||
device = Devices[index];
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
device = default(T);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public T FromHardwareId(long id)
|
||||
{
|
||||
if (Map.ContainsKey(id))
|
||||
{
|
||||
return FromIndex(Map[id]);
|
||||
}
|
||||
else
|
||||
{
|
||||
return default(T);
|
||||
}
|
||||
}
|
||||
|
||||
public bool FromHardwareId(long id, out T device)
|
||||
{
|
||||
if (Map.ContainsKey(id))
|
||||
{
|
||||
device = FromIndex(Map[id]);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
device = default(T);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return Map.Count; }
|
||||
}
|
||||
|
||||
// Return the index of the first empty slot in Devices.
|
||||
// If no empty slot exists, append a new one and return
|
||||
// that index.
|
||||
private int GetIndex()
|
||||
{
|
||||
for (int i = 0; i < Devices.Count; i++)
|
||||
{
|
||||
if (Devices[i] == null)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
Devices.Add(default(T));
|
||||
return Devices.Count - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
61
GLWidget/OpenTK/Platform/DisplayDeviceBase.cs
Normal file
61
GLWidget/OpenTK/Platform/DisplayDeviceBase.cs
Normal file
|
@ -0,0 +1,61 @@
|
|||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2010 the Open Toolkit library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace OpenTK.Platform
|
||||
{
|
||||
internal abstract class DisplayDeviceBase : IDisplayDeviceDriver
|
||||
{
|
||||
internal sealed class SystemEvents
|
||||
{
|
||||
public static event EventHandler DisplaySettingsChanged;
|
||||
}
|
||||
|
||||
protected readonly List<DisplayDevice> AvailableDevices = new List<DisplayDevice>();
|
||||
protected DisplayDevice Primary;
|
||||
|
||||
public abstract bool TryChangeResolution(DisplayDevice device, DisplayResolution resolution);
|
||||
public abstract bool TryRestoreResolution(DisplayDevice device);
|
||||
|
||||
// Gets the DisplayDevice that corresponds to the specified index.
|
||||
public virtual DisplayDevice GetDisplay(DisplayIndex index)
|
||||
{
|
||||
if (index == DisplayIndex.Primary)
|
||||
{
|
||||
return Primary;
|
||||
}
|
||||
else if ((int)index >= 0 && (int)index < AvailableDevices.Count)
|
||||
{
|
||||
return AvailableDevices[(int)index];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
97
GLWidget/OpenTK/Platform/Dummy/DummyGLContext.cs
Normal file
97
GLWidget/OpenTK/Platform/Dummy/DummyGLContext.cs
Normal file
|
@ -0,0 +1,97 @@
|
|||
/* Licensed under the MIT/X11 license.
|
||||
* Copyright (c) 2006-2008 the OpenTK Team.
|
||||
* This notice may not be removed from any source distribution.
|
||||
* See license.txt for licensing detailed licensing details.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace OpenTK.Platform.Dummy
|
||||
{
|
||||
/// \internal
|
||||
/// <summary>
|
||||
/// An empty IGraphicsContext implementation to be used inside the Visual Studio designer.
|
||||
/// This class supports OpenTK, and is not intended for use by OpenTK programs.
|
||||
/// </summary>
|
||||
internal sealed class DummyGLContext : GraphicsContextBase
|
||||
{
|
||||
private readonly GraphicsContext.GetAddressDelegate Loader;
|
||||
|
||||
private static int handle_count;
|
||||
private Thread current_thread;
|
||||
|
||||
public DummyGLContext()
|
||||
{
|
||||
Handle = new ContextHandle(
|
||||
new IntPtr(Interlocked.Increment(
|
||||
ref handle_count)));
|
||||
}
|
||||
|
||||
public DummyGLContext(ContextHandle handle, GraphicsContext.GetAddressDelegate loader)
|
||||
: this()
|
||||
{
|
||||
if (handle != ContextHandle.Zero)
|
||||
{
|
||||
Handle = handle;
|
||||
}
|
||||
Loader = loader;
|
||||
Mode = new GraphicsMode(new IntPtr(2), 32, 16, 0, 0, 0, 2, false);
|
||||
}
|
||||
|
||||
public override void SwapBuffers() { }
|
||||
|
||||
public override void MakeCurrent(IWindowInfo info)
|
||||
{
|
||||
Thread new_thread = Thread.CurrentThread;
|
||||
// A context may be current only on one thread at a time.
|
||||
if (current_thread != null && new_thread != current_thread)
|
||||
{
|
||||
throw new GraphicsContextException(
|
||||
"Cannot make context current on two threads at the same time");
|
||||
}
|
||||
|
||||
if (info != null)
|
||||
{
|
||||
current_thread = Thread.CurrentThread;
|
||||
}
|
||||
else
|
||||
{
|
||||
current_thread = null;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsCurrent
|
||||
{
|
||||
get { return current_thread != null && current_thread == Thread.CurrentThread; }
|
||||
}
|
||||
|
||||
public override IntPtr GetAddress(IntPtr function)
|
||||
{
|
||||
string str = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(function);
|
||||
return Loader(str);
|
||||
}
|
||||
|
||||
public override int SwapInterval { get; set; }
|
||||
|
||||
public override void Update(IWindowInfo window)
|
||||
{ }
|
||||
|
||||
public override void LoadAll()
|
||||
{
|
||||
#if OPENGL
|
||||
new OpenTK.Graphics.OpenGL.GL().LoadEntryPoints();
|
||||
new OpenTK.Graphics.OpenGL4.GL().LoadEntryPoints();
|
||||
#endif
|
||||
#if OPENGLES
|
||||
new OpenTK.Graphics.ES11.GL().LoadEntryPoints();
|
||||
new OpenTK.Graphics.ES20.GL().LoadEntryPoints();
|
||||
new OpenTK.Graphics.ES30.GL().LoadEntryPoints();
|
||||
#endif
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing) { IsDisposed = true; }
|
||||
}
|
||||
}
|
16
GLWidget/OpenTK/Platform/Dummy/DummyWindowInfo.cs
Normal file
16
GLWidget/OpenTK/Platform/Dummy/DummyWindowInfo.cs
Normal file
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
|
||||
namespace OpenTK.Platform.Dummy
|
||||
{
|
||||
internal class DummyWindowInfo : IWindowInfo
|
||||
{
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
public IntPtr Handle
|
||||
{
|
||||
get { return IntPtr.Zero; }
|
||||
}
|
||||
}
|
||||
}
|
179
GLWidget/OpenTK/Platform/Egl/AngleWindowInfo.cs
Normal file
179
GLWidget/OpenTK/Platform/Egl/AngleWindowInfo.cs
Normal file
|
@ -0,0 +1,179 @@
|
|||
using System;
|
||||
using OpenTK.Graphics;
|
||||
using OpenTK.Platform.Windows;
|
||||
|
||||
namespace OpenTK.Platform.Egl
|
||||
{
|
||||
using EGLSurface = IntPtr;
|
||||
/// <summary>
|
||||
/// A window info for angle.
|
||||
/// </summary>
|
||||
public interface IAngleWindowInfo : IWindowInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Query the underlying platform pointer / handle for this window's
|
||||
/// default surface or IntPtr.Zero
|
||||
/// </summary>
|
||||
IntPtr QuerySurfacePointer();
|
||||
/// <summary>
|
||||
/// Create an additional rendering surface that shares the display
|
||||
/// of this window.
|
||||
/// </summary>
|
||||
/// <param name="width">width in pixels</param>
|
||||
/// <param name="height">height in pixels</param>
|
||||
/// <returns>A reference to the new surface</returns>
|
||||
EGLSurface CreateSurface(int width, int height);
|
||||
/// <summary>
|
||||
/// Destroy a surface created with CreateSurface and clears the passed reference.
|
||||
/// </summary>
|
||||
/// <param name="surface">Reference to the surface.</param>
|
||||
void DestroySurface(ref EGLSurface surface);
|
||||
/// <summary>
|
||||
/// MakeCurrent the custom surface created with CreateSurface.
|
||||
/// </summary>
|
||||
/// <param name="surface">Reference to the surface.</param>
|
||||
void MakeCurrent(EGLSurface surface);
|
||||
/// <summary>
|
||||
/// Query the underlying platform pointer / handle for an EGLSurface
|
||||
/// created with CreateSurface.
|
||||
/// </summary>
|
||||
/// <param name="surface"></param>
|
||||
IntPtr QuerySurfacePointer(EGLSurface surface);
|
||||
}
|
||||
|
||||
internal interface IAngleWindowInfoInternal : IAngleWindowInfo
|
||||
{
|
||||
IWindowInfo PlatformWindow { get; }
|
||||
IntPtr Display { get; }
|
||||
IntPtr Surface { get; }
|
||||
EglContext EglContext { get; set; }
|
||||
EglWindowInfo EglWindowInfo { get; set; }
|
||||
IntPtr DeviceContext { get; }
|
||||
}
|
||||
|
||||
internal class AngleWindowInfo : IAngleWindowInfoInternal
|
||||
{
|
||||
private bool _disposed;
|
||||
|
||||
public AngleWindowInfo(IWindowInfo platform_window)
|
||||
{
|
||||
PlatformWindow = platform_window;
|
||||
}
|
||||
|
||||
public IWindowInfo PlatformWindow { get; }
|
||||
|
||||
public IWindowInfo WindowInfo
|
||||
{
|
||||
get { return EglWindowInfo; }
|
||||
}
|
||||
|
||||
public IntPtr DeviceContext
|
||||
{
|
||||
get
|
||||
{
|
||||
var win_win = PlatformWindow as WinWindowInfo;
|
||||
if (win_win != null)
|
||||
{
|
||||
return win_win.DeviceContext;
|
||||
}
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
public EglContext EglContext { get; set; }
|
||||
public EglWindowInfo EglWindowInfo { get; set; }
|
||||
|
||||
public IntPtr Display
|
||||
{
|
||||
get { return EglWindowInfo.Display; }
|
||||
}
|
||||
|
||||
public IntPtr Surface
|
||||
{
|
||||
get { return EglWindowInfo.Surface; }
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
public IntPtr Handle
|
||||
{
|
||||
get { return PlatformWindow.Handle; }
|
||||
}
|
||||
|
||||
~AngleWindowInfo()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
private void Dispose(bool called_from_finalizer)
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!called_from_finalizer)
|
||||
{
|
||||
PlatformWindow.Dispose();
|
||||
}
|
||||
// dispose unmanaged
|
||||
|
||||
_disposed = true;
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
public IntPtr QuerySurfacePointer()
|
||||
{
|
||||
return QuerySurfacePointer(Surface);
|
||||
}
|
||||
|
||||
public EGLSurface CreateSurface(int width, int height)
|
||||
{
|
||||
IntPtr surface;
|
||||
EglWindowInfo.CreatePbufferSurface(
|
||||
EglContext.GraphicsMode.Index.Value,
|
||||
width, height,
|
||||
out surface);
|
||||
return surface;
|
||||
}
|
||||
|
||||
public void DestroySurface(ref EGLSurface surface)
|
||||
{
|
||||
EglWindowInfo.DestroySurface(ref surface);
|
||||
}
|
||||
|
||||
public void MakeCurrent(EGLSurface surface)
|
||||
{
|
||||
Egl.MakeCurrent(Display, surface, surface, EglContext.HandleAsEGLContext);
|
||||
}
|
||||
|
||||
public IntPtr QuerySurfacePointer(IntPtr surface)
|
||||
{
|
||||
if (UsesDirect3DBackend())
|
||||
{
|
||||
return QuerySurfacePointer(surface,
|
||||
Egl.EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE);
|
||||
}
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
private IntPtr QuerySurfacePointer(IntPtr surface, int attrib)
|
||||
{
|
||||
IntPtr surface_pointer;
|
||||
if (Egl.QuerySurfacePointerANGLE(
|
||||
Display, surface, attrib, out surface_pointer))
|
||||
{
|
||||
return surface_pointer;
|
||||
}
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
private bool UsesDirect3DBackend()
|
||||
{
|
||||
var d3d_flags = GraphicsContextFlags.AngleD3D9 | GraphicsContextFlags.AngleD3D11;
|
||||
return ((EglContext.GraphicsContextFlags & d3d_flags) != 0);
|
||||
}
|
||||
}
|
||||
}
|
403
GLWidget/OpenTK/Platform/Egl/Egl.cs
Normal file
403
GLWidget/OpenTK/Platform/Egl/Egl.cs
Normal file
|
@ -0,0 +1,403 @@
|
|||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2011 the Open Toolkit library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
// ReSharper disable InconsistentNaming
|
||||
// ReSharper disable UnusedMember.Global
|
||||
|
||||
#pragma warning disable 1591 // Missing XML comments
|
||||
|
||||
namespace OpenTK.Platform.Egl
|
||||
{
|
||||
using EGLNativeDisplayType = IntPtr;
|
||||
using EGLNativeWindowType = IntPtr;
|
||||
using EGLNativePixmapType = IntPtr;
|
||||
using EGLConfig = IntPtr;
|
||||
using EGLContext = IntPtr;
|
||||
using EGLDisplay = IntPtr;
|
||||
using EGLSurface = IntPtr;
|
||||
using EGLClientBuffer = IntPtr;
|
||||
|
||||
internal enum RenderApi
|
||||
{
|
||||
ES = Egl.OPENGL_ES_API,
|
||||
GL = Egl.OPENGL_API,
|
||||
VG = Egl.OPENVG_API
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum RenderableFlags
|
||||
{
|
||||
ES = Egl.OPENGL_ES_BIT,
|
||||
ES2 = Egl.OPENGL_ES2_BIT,
|
||||
ES3 = Egl.OPENGL_ES3_BIT,
|
||||
GL = Egl.OPENGL_BIT,
|
||||
VG = Egl.OPENVG_BIT,
|
||||
}
|
||||
|
||||
public enum ErrorCode
|
||||
{
|
||||
SUCCESS = 12288,
|
||||
NOT_INITIALIZED = 12289,
|
||||
BAD_ACCESS = 12290,
|
||||
BAD_ALLOC = 12291,
|
||||
BAD_ATTRIBUTE = 12292,
|
||||
BAD_CONFIG = 12293,
|
||||
BAD_CONTEXT = 12294,
|
||||
BAD_CURRENT_SURFACE = 12295,
|
||||
BAD_DISPLAY = 12296,
|
||||
BAD_MATCH = 12297,
|
||||
BAD_NATIVE_PIXMAP = 12298,
|
||||
BAD_NATIVE_WINDOW = 12299,
|
||||
BAD_PARAMETER = 12300,
|
||||
BAD_SURFACE = 12301,
|
||||
CONTEXT_LOST = 12302,
|
||||
}
|
||||
|
||||
internal enum SurfaceType
|
||||
{
|
||||
PBUFFER_BIT = 0x0001,
|
||||
PIXMAP_BIT = 0x0002,
|
||||
WINDOW_BIT = 0x0004,
|
||||
VG_COLORSPACE_LINEAR_BIT = 0x0020,
|
||||
VG_ALPHA_FORMAT_PRE_BIT = 0x0040,
|
||||
MULTISAMPLE_RESOLVE_BOX_BIT = 0x0200,
|
||||
SWAP_BEHAVIOR_PRESERVED_BIT = 0x0400,
|
||||
}
|
||||
|
||||
internal static partial class Egl
|
||||
{
|
||||
public const int VERSION_1_0 = 1;
|
||||
public const int VERSION_1_1 = 1;
|
||||
public const int VERSION_1_2 = 1;
|
||||
public const int VERSION_1_3 = 1;
|
||||
public const int VERSION_1_4 = 1;
|
||||
public const int FALSE = 0;
|
||||
public const int TRUE = 1;
|
||||
public const int DONT_CARE = -1;
|
||||
public const int CONTEXT_LOST = 12302;
|
||||
public const int BUFFER_SIZE = 12320;
|
||||
public const int ALPHA_SIZE = 12321;
|
||||
public const int BLUE_SIZE = 12322;
|
||||
public const int GREEN_SIZE = 12323;
|
||||
public const int RED_SIZE = 12324;
|
||||
public const int DEPTH_SIZE = 12325;
|
||||
public const int STENCIL_SIZE = 12326;
|
||||
public const int CONFIG_CAVEAT = 12327;
|
||||
public const int CONFIG_ID = 12328;
|
||||
public const int LEVEL = 12329;
|
||||
public const int MAX_PBUFFER_HEIGHT = 12330;
|
||||
public const int MAX_PBUFFER_PIXELS = 12331;
|
||||
public const int MAX_PBUFFER_WIDTH = 12332;
|
||||
public const int NATIVE_RENDERABLE = 12333;
|
||||
public const int NATIVE_VISUAL_ID = 12334;
|
||||
public const int NATIVE_VISUAL_TYPE = 12335;
|
||||
public const int PRESERVED_RESOURCES = 12336;
|
||||
public const int SAMPLES = 12337;
|
||||
public const int SAMPLE_BUFFERS = 12338;
|
||||
public const int SURFACE_TYPE = 12339;
|
||||
public const int TRANSPARENT_TYPE = 12340;
|
||||
public const int TRANSPARENT_BLUE_VALUE = 12341;
|
||||
public const int TRANSPARENT_GREEN_VALUE = 12342;
|
||||
public const int TRANSPARENT_RED_VALUE = 12343;
|
||||
public const int NONE = 12344;
|
||||
public const int BIND_TO_TEXTURE_RGB = 12345;
|
||||
public const int BIND_TO_TEXTURE_RGBA = 12346;
|
||||
public const int MIN_SWAP_INTERVAL = 12347;
|
||||
public const int MAX_SWAP_INTERVAL = 12348;
|
||||
public const int LUMINANCE_SIZE = 12349;
|
||||
public const int ALPHA_MASK_SIZE = 12350;
|
||||
public const int COLOR_BUFFER_TYPE = 12351;
|
||||
public const int RENDERABLE_TYPE = 12352;
|
||||
public const int MATCH_NATIVE_PIXMAP = 12353;
|
||||
public const int CONFORMANT = 12354;
|
||||
public const int SLOW_CONFIG = 12368;
|
||||
public const int NON_CONFORMANT_CONFIG = 12369;
|
||||
public const int TRANSPARENT_RGB = 12370;
|
||||
public const int RGB_BUFFER = 12430;
|
||||
public const int LUMINANCE_BUFFER = 12431;
|
||||
public const int NO_TEXTURE = 12380;
|
||||
public const int TEXTURE_RGB = 12381;
|
||||
public const int TEXTURE_RGBA = 12382;
|
||||
public const int TEXTURE_2D = 12383;
|
||||
public const int PBUFFER_BIT = 1;
|
||||
public const int PIXMAP_BIT = 2;
|
||||
public const int WINDOW_BIT = 4;
|
||||
public const int VG_COLORSPACE_LINEAR_BIT = 32;
|
||||
public const int VG_ALPHA_FORMAT_PRE_BIT = 64;
|
||||
public const int MULTISAMPLE_RESOLVE_BOX_BIT = 512;
|
||||
public const int SWAP_BEHAVIOR_PRESERVED_BIT = 1024;
|
||||
public const int OPENGL_ES_BIT = 1;
|
||||
public const int OPENVG_BIT = 2;
|
||||
public const int OPENGL_ES2_BIT = 4;
|
||||
public const int OPENGL_BIT = 8;
|
||||
public const int OPENGL_ES3_BIT = 64;
|
||||
public const int VENDOR = 12371;
|
||||
public const int VERSION = 12372;
|
||||
public const int EXTENSIONS = 12373;
|
||||
public const int CLIENT_APIS = 12429;
|
||||
public const int HEIGHT = 12374;
|
||||
public const int WIDTH = 12375;
|
||||
public const int LARGEST_PBUFFER = 12376;
|
||||
public const int TEXTURE_FORMAT = 12416;
|
||||
public const int TEXTURE_TARGET = 12417;
|
||||
public const int MIPMAP_TEXTURE = 12418;
|
||||
public const int MIPMAP_LEVEL = 12419;
|
||||
public const int RENDER_BUFFER = 12422;
|
||||
public const int VG_COLORSPACE = 12423;
|
||||
public const int VG_ALPHA_FORMAT = 12424;
|
||||
public const int HORIZONTAL_RESOLUTION = 12432;
|
||||
public const int VERTICAL_RESOLUTION = 12433;
|
||||
public const int PIXEL_ASPECT_RATIO = 12434;
|
||||
public const int SWAP_BEHAVIOR = 12435;
|
||||
public const int MULTISAMPLE_RESOLVE = 12441;
|
||||
public const int BACK_BUFFER = 12420;
|
||||
public const int SINGLE_BUFFER = 12421;
|
||||
public const int VG_COLORSPACE_sRGB = 12425;
|
||||
public const int VG_COLORSPACE_LINEAR = 12426;
|
||||
public const int VG_ALPHA_FORMAT_NONPRE = 12427;
|
||||
public const int VG_ALPHA_FORMAT_PRE = 12428;
|
||||
public const int DISPLAY_SCALING = 10000;
|
||||
public const int UNKNOWN = -1;
|
||||
public const int BUFFER_PRESERVED = 12436;
|
||||
public const int BUFFER_DESTROYED = 12437;
|
||||
public const int OPENVG_IMAGE = 12438;
|
||||
public const int CONTEXT_CLIENT_TYPE = 12439;
|
||||
public const int CONTEXT_CLIENT_VERSION = 12440;
|
||||
public const int MULTISAMPLE_RESOLVE_DEFAULT = 12442;
|
||||
public const int MULTISAMPLE_RESOLVE_BOX = 12443;
|
||||
public const int OPENGL_ES_API = 12448;
|
||||
public const int OPENVG_API = 12449;
|
||||
public const int OPENGL_API = 12450;
|
||||
public const int DRAW = 12377;
|
||||
public const int READ = 12378;
|
||||
public const int CORE_NATIVE_ENGINE = 12379;
|
||||
public const int COLORSPACE = VG_COLORSPACE;
|
||||
public const int ALPHA_FORMAT = VG_ALPHA_FORMAT;
|
||||
public const int COLORSPACE_sRGB = VG_COLORSPACE_sRGB;
|
||||
public const int COLORSPACE_LINEAR = VG_COLORSPACE_LINEAR;
|
||||
public const int ALPHA_FORMAT_NONPRE = VG_ALPHA_FORMAT_NONPRE;
|
||||
public const int ALPHA_FORMAT_PRE = VG_ALPHA_FORMAT_PRE;
|
||||
|
||||
// EGL_ANGLE_d3d_share_handle_client_buffer
|
||||
public const int D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE = 0x3200;
|
||||
// EGL_ANGLE_window_fixed_size
|
||||
public const int FIXED_SIZE_ANGLE = 0x3201;
|
||||
// EGL_ANGLE_query_surface_pointer
|
||||
[DllImport("libEGL.dll", EntryPoint = "eglQuerySurfacePointerANGLE")]
|
||||
public static extern bool QuerySurfacePointerANGLE(EGLDisplay display, EGLSurface surface, int attribute, out IntPtr value);
|
||||
|
||||
[DllImport("libEGL.dll", EntryPoint = "eglGetPlatformDisplayEXT")]
|
||||
public static extern EGLDisplay GetPlatformDisplay(int platform, EGLNativeDisplayType displayId, int[] attribList);
|
||||
|
||||
// EGL_ANGLE_software_display
|
||||
public static readonly EGLNativeDisplayType SOFTWARE_DISPLAY_ANGLE = new EGLNativeDisplayType(-1);
|
||||
// EGL_ANGLE_direct3d_display
|
||||
public static readonly EGLNativeDisplayType D3D11_ELSE_D3D9_DISPLAY_ANGLE = new EGLNativeDisplayType(-2);
|
||||
public static readonly EGLNativeDisplayType D3D11_ONLY_DISPLAY_ANGLE = new EGLNativeDisplayType(-3);
|
||||
// EGL_ANGLE_device_d3d
|
||||
public const int D3D9_DEVICE_ANGLE = 0x33A0;
|
||||
public const int D3D11_DEVICE_ANGLE = 0x33A1;
|
||||
// EGL_ANGLE_platform_angle
|
||||
public const int PLATFORM_ANGLE_ANGLE = 0x3202;
|
||||
public const int PLATFORM_ANGLE_TYPE_ANGLE = 0x3203;
|
||||
public const int PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE = 0x3204;
|
||||
public const int PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE = 0x3205;
|
||||
public const int PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE = 0x3206;
|
||||
// EGL_ANGLE_platform_angle_d3d
|
||||
public const int PLATFORM_ANGLE_TYPE_D3D9_ANGLE = 0x3207;
|
||||
public const int PLATFORM_ANGLE_TYPE_D3D11_ANGLE = 0x3208;
|
||||
public const int PLATFORM_ANGLE_DEVICE_TYPE_ANGLE = 0x3209;
|
||||
public const int PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE = 0x320A;
|
||||
public const int PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE = 0x320B;
|
||||
public const int PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE = 0x320C;
|
||||
public const int PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE = 0x320F;
|
||||
// EGL_ANGLE_platform_angle_opengl
|
||||
public const int PLATFORM_ANGLE_TYPE_OPENGL_ANGLE = 0x320D;
|
||||
public const int PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE = 0x320E;
|
||||
// See EGL_ANGLE_surface_d3d_texture_2d_share_handle
|
||||
public const int EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE = 0x3200;
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglGetError")]
|
||||
public static extern ErrorCode GetError();
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglGetDisplay")]
|
||||
public static extern EGLDisplay GetDisplay(EGLNativeDisplayType display_id);
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglInitialize")]
|
||||
//[return: MarshalAsAttribute(UnmanagedType.I1)]
|
||||
public static extern bool Initialize(EGLDisplay dpy, out int major, out int minor);
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglTerminate")]
|
||||
//[return: MarshalAsAttribute(UnmanagedType.I1)]
|
||||
public static extern bool Terminate(EGLDisplay dpy);
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglQueryString")]
|
||||
public static extern IntPtr QueryString(EGLDisplay dpy, int name);
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglGetConfigs")]
|
||||
[return: MarshalAsAttribute(UnmanagedType.I1)]
|
||||
public static extern bool GetConfigs(EGLDisplay dpy, EGLConfig[] configs, int config_size, out int num_config);
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglChooseConfig")]
|
||||
[return: MarshalAsAttribute(UnmanagedType.I1)]
|
||||
public static extern bool ChooseConfig(EGLDisplay dpy, int[] attrib_list, [In, Out] EGLConfig[] configs, int config_size, out int num_config);
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglGetConfigAttrib")]
|
||||
[return: MarshalAsAttribute(UnmanagedType.I1)]
|
||||
public static extern bool GetConfigAttrib(EGLDisplay dpy, EGLConfig config, int attribute, out int value);
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglCreateWindowSurface")]
|
||||
public static extern EGLSurface CreateWindowSurface(EGLDisplay dpy, EGLConfig config, IntPtr win, IntPtr attrib_list);
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglCreatePbufferSurface")]
|
||||
public static extern EGLSurface CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, int[] attrib_list);
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglCreatePixmapSurface")]
|
||||
public static extern EGLSurface CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, int[] attrib_list);
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglDestroySurface")]
|
||||
[return: MarshalAsAttribute(UnmanagedType.I1)]
|
||||
public static extern bool DestroySurface(EGLDisplay dpy, EGLSurface surface);
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglQuerySurface")]
|
||||
[return: MarshalAsAttribute(UnmanagedType.I1)]
|
||||
public static extern bool QuerySurface(EGLDisplay dpy, EGLSurface surface, int attribute, out int value);
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglBindAPI")]
|
||||
[return: MarshalAsAttribute(UnmanagedType.I1)]
|
||||
public static extern bool BindAPI(RenderApi api);
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglQueryAPI")]
|
||||
public static extern int QueryAPI();
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglWaitClient")]
|
||||
[return: MarshalAsAttribute(UnmanagedType.I1)]
|
||||
public static extern bool WaitClient();
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglReleaseThread")]
|
||||
[return: MarshalAsAttribute(UnmanagedType.I1)]
|
||||
public static extern bool ReleaseThread();
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglCreatePbufferFromClientBuffer")]
|
||||
public static extern EGLSurface CreatePbufferFromClientBuffer(EGLDisplay dpy, int buftype, EGLClientBuffer buffer, EGLConfig config, int[] attrib_list);
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglSurfaceAttrib")]
|
||||
[return: MarshalAsAttribute(UnmanagedType.I1)]
|
||||
public static extern bool SurfaceAttrib(EGLDisplay dpy, EGLSurface surface, int attribute, int value);
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglBindTexImage")]
|
||||
[return: MarshalAsAttribute(UnmanagedType.I1)]
|
||||
public static extern bool BindTexImage(EGLDisplay dpy, EGLSurface surface, int buffer);
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglReleaseTexImage")]
|
||||
[return: MarshalAsAttribute(UnmanagedType.I1)]
|
||||
public static extern bool ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, int buffer);
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglSwapInterval")]
|
||||
[return: MarshalAsAttribute(UnmanagedType.I1)]
|
||||
public static extern bool SwapInterval(EGLDisplay dpy, int interval);
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglCreateContext")]
|
||||
private static extern IntPtr eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, int[] attrib_list);
|
||||
|
||||
public static EGLContext CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, int[] attrib_list)
|
||||
{
|
||||
IntPtr ptr = eglCreateContext(dpy, config, share_context, attrib_list);
|
||||
if (ptr == IntPtr.Zero)
|
||||
{
|
||||
throw new GraphicsContextException(String.Format("Failed to create EGL context, error: {0}.", Egl.GetError()));
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglDestroyContext")]
|
||||
[return: MarshalAsAttribute(UnmanagedType.I1)]
|
||||
public static extern bool DestroyContext(EGLDisplay dpy, EGLContext ctx);
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglMakeCurrent")]
|
||||
[return: MarshalAsAttribute(UnmanagedType.I1)]
|
||||
public static extern bool MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglGetCurrentContext")]
|
||||
public static extern EGLContext GetCurrentContext();
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglGetCurrentSurface")]
|
||||
public static extern EGLSurface GetCurrentSurface(int readdraw);
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglGetCurrentDisplay")]
|
||||
public static extern EGLDisplay GetCurrentDisplay();
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglQueryContext")]
|
||||
[return: MarshalAsAttribute(UnmanagedType.I1)]
|
||||
public static extern bool QueryContext(EGLDisplay dpy, EGLContext ctx, int attribute, out int value);
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglWaitGL")]
|
||||
[return: MarshalAsAttribute(UnmanagedType.I1)]
|
||||
public static extern bool WaitGL();
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglWaitNative")]
|
||||
[return: MarshalAsAttribute(UnmanagedType.I1)]
|
||||
public static extern bool WaitNative(int engine);
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglSwapBuffers")]
|
||||
[return: MarshalAsAttribute(UnmanagedType.I1)]
|
||||
public static extern bool SwapBuffers(EGLDisplay dpy, EGLSurface surface);
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglCopyBuffers")]
|
||||
[return: MarshalAsAttribute(UnmanagedType.I1)]
|
||||
public static extern bool CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target);
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglGetProcAddress")]
|
||||
public static extern IntPtr GetProcAddress(string funcname);
|
||||
|
||||
[DllImportAttribute("libEGL.dll", EntryPoint = "eglGetProcAddress")]
|
||||
public static extern IntPtr GetProcAddress(IntPtr funcname);
|
||||
|
||||
// EGL_EXT_platform_base
|
||||
[DllImport("libEGL.dll", EntryPoint = "eglGetPlatformDisplayEXT")]
|
||||
public static extern EGLDisplay GetPlatformDisplayEXT(int platform, EGLNativeDisplayType native_display, int[] attrib_list);
|
||||
|
||||
[DllImport("libEGL.dll", EntryPoint = "eglCreatePlatformWindowSurfaceEXT")]
|
||||
public static extern EGLSurface CreatePlatformWindowSurfaceEXT(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType native_window, int[] attrib_list);
|
||||
|
||||
[DllImport("libEGL.dll", EntryPoint = "eglCreatePlatformPixmapSurfaceEXT")]
|
||||
public static extern EGLSurface CreatePlatformPixmapSurfaceEXT(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType native_pixmap, int[] attrib_list);
|
||||
|
||||
// Returns true if Egl drivers exist on the system.
|
||||
public static bool IsSupported
|
||||
{
|
||||
get
|
||||
{
|
||||
try { GetCurrentContext(); }
|
||||
catch (Exception) { return false; }
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
138
GLWidget/OpenTK/Platform/Egl/EglAnglePlatformFactory.cs
Normal file
138
GLWidget/OpenTK/Platform/Egl/EglAnglePlatformFactory.cs
Normal file
|
@ -0,0 +1,138 @@
|
|||
|
||||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2015 the Open Toolkit library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace OpenTK.Platform.Egl
|
||||
{
|
||||
internal class EglAnglePlatformFactory : PlatformFactoryBase
|
||||
{
|
||||
private readonly IPlatformFactory _platform_factory;
|
||||
public EglAnglePlatformFactory(IPlatformFactory platform_factory)
|
||||
{
|
||||
_platform_factory = platform_factory;
|
||||
}
|
||||
|
||||
public override IDisplayDeviceDriver CreateDisplayDeviceDriver()
|
||||
{
|
||||
return _platform_factory.CreateDisplayDeviceDriver();
|
||||
}
|
||||
|
||||
public override IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window,
|
||||
IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
|
||||
{
|
||||
var angle_window = (IAngleWindowInfoInternal)window;
|
||||
var egl_window = CreateWindowInfo(angle_window, major, flags);
|
||||
var egl_context = new EglWinContext(mode, egl_window, shareContext, major, minor, flags);
|
||||
angle_window.EglContext = egl_context;
|
||||
return egl_context;
|
||||
}
|
||||
|
||||
public override IGraphicsContext CreateGLContext(ContextHandle handle, IWindowInfo window,
|
||||
IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
|
||||
{
|
||||
var angle_window = (IAngleWindowInfoInternal)window;
|
||||
var egl_window = CreateWindowInfo(angle_window, major, flags);
|
||||
var egl_context = new EglWinContext(handle, egl_window, shareContext, major, minor, flags);
|
||||
angle_window.EglContext = egl_context;
|
||||
return egl_context;
|
||||
}
|
||||
|
||||
public override GraphicsContext.GetCurrentContextDelegate CreateGetCurrentGraphicsContext()
|
||||
{
|
||||
return (GraphicsContext.GetCurrentContextDelegate)delegate
|
||||
{
|
||||
return new ContextHandle(Platform.Egl.Egl.GetCurrentContext());
|
||||
};
|
||||
}
|
||||
|
||||
private static bool FlagEnabled(GraphicsContextFlags flags, GraphicsContextFlags flag)
|
||||
{
|
||||
return (flags & flag) != 0;
|
||||
}
|
||||
|
||||
private EglWindowInfo CreateWindowInfo(IAngleWindowInfoInternal window_info,
|
||||
int major, GraphicsContextFlags flags)
|
||||
{
|
||||
var egl_display = GetAngleDisplay(window_info.DeviceContext, flags, major);
|
||||
var egl_window = new EglWindowInfo(window_info.Handle, egl_display);
|
||||
window_info.EglWindowInfo = egl_window;
|
||||
return egl_window;
|
||||
}
|
||||
|
||||
private IntPtr GetAngleDisplay(IntPtr dc, GraphicsContextFlags flags, int major)
|
||||
{
|
||||
// default to D3D9 for ES2, but use D3D11 for ES3 as required by Angle.
|
||||
var platform_type = major == 2
|
||||
? Platform.Egl.Egl.PLATFORM_ANGLE_TYPE_D3D9_ANGLE
|
||||
: Platform.Egl.Egl.PLATFORM_ANGLE_TYPE_D3D11_ANGLE;
|
||||
if (FlagEnabled(flags, GraphicsContextFlags.AngleD3D11))
|
||||
{
|
||||
platform_type = Platform.Egl.Egl.PLATFORM_ANGLE_TYPE_D3D11_ANGLE;
|
||||
}
|
||||
else if (FlagEnabled(flags, GraphicsContextFlags.AngleD3D9))
|
||||
{
|
||||
platform_type = Platform.Egl.Egl.PLATFORM_ANGLE_TYPE_D3D9_ANGLE;
|
||||
}
|
||||
else if (FlagEnabled(flags, GraphicsContextFlags.AngleOpenGL))
|
||||
{
|
||||
platform_type = Platform.Egl.Egl.PLATFORM_ANGLE_TYPE_OPENGL_ANGLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// make sure the correct flag is set.
|
||||
switch (platform_type)
|
||||
{
|
||||
case Platform.Egl.Egl.PLATFORM_ANGLE_TYPE_D3D9_ANGLE:
|
||||
flags |= GraphicsContextFlags.AngleD3D9;
|
||||
break;
|
||||
case Platform.Egl.Egl.PLATFORM_ANGLE_TYPE_D3D11_ANGLE:
|
||||
flags |= GraphicsContextFlags.AngleD3D11;
|
||||
break;
|
||||
case Platform.Egl.Egl.PLATFORM_ANGLE_TYPE_OPENGL_ANGLE:
|
||||
flags |= GraphicsContextFlags.AngleOpenGL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var attribs = new[]
|
||||
{
|
||||
Platform.Egl.Egl.PLATFORM_ANGLE_TYPE_ANGLE, platform_type,
|
||||
Platform.Egl.Egl.PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, Platform.Egl.Egl.DONT_CARE,
|
||||
Platform.Egl.Egl.PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE, Platform.Egl.Egl.DONT_CARE,
|
||||
Platform.Egl.Egl.PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, Platform.Egl.Egl.PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE,
|
||||
Platform.Egl.Egl.NONE
|
||||
};
|
||||
|
||||
return Platform.Egl.Egl.GetPlatformDisplay(
|
||||
Platform.Egl.Egl.PLATFORM_ANGLE_ANGLE,
|
||||
dc,
|
||||
attribs
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
268
GLWidget/OpenTK/Platform/Egl/EglContext.cs
Normal file
268
GLWidget/OpenTK/Platform/Egl/EglContext.cs
Normal file
|
@ -0,0 +1,268 @@
|
|||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2009 the Open Toolkit library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace OpenTK.Platform.Egl
|
||||
{
|
||||
internal abstract class EglContext : EmbeddedGraphicsContext
|
||||
{
|
||||
protected readonly RenderableFlags Renderable;
|
||||
internal EglWindowInfo WindowInfo;
|
||||
|
||||
internal GraphicsContextFlags GraphicsContextFlags { get; set; }
|
||||
|
||||
internal IntPtr HandleAsEGLContext { get { return Handle.Handle; } set { Handle = new ContextHandle(value); } }
|
||||
private int swap_interval = 1; // Default interval is defined as 1 in EGL.
|
||||
|
||||
public EglContext(GraphicsMode mode, EglWindowInfo window, IGraphicsContext sharedContext,
|
||||
int major, int minor, GraphicsContextFlags flags)
|
||||
{
|
||||
if (mode == null)
|
||||
{
|
||||
throw new ArgumentNullException("mode");
|
||||
}
|
||||
if (window == null)
|
||||
{
|
||||
throw new ArgumentNullException("window");
|
||||
}
|
||||
|
||||
EglContext shared = GetSharedEglContext(sharedContext);
|
||||
|
||||
WindowInfo = window;
|
||||
|
||||
// Select an EGLConfig that matches the desired mode. We cannot use the 'mode'
|
||||
// parameter directly, since it may have originated on a different system (e.g. GLX)
|
||||
// and it may not support the desired renderer.
|
||||
|
||||
Renderable = RenderableFlags.GL;
|
||||
if ((flags & GraphicsContextFlags.Embedded) != 0)
|
||||
{
|
||||
switch (major)
|
||||
{
|
||||
case 3:
|
||||
Renderable = RenderableFlags.ES3;
|
||||
break;
|
||||
case 2:
|
||||
Renderable = RenderableFlags.ES2;
|
||||
break;
|
||||
default:
|
||||
Renderable = RenderableFlags.ES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RenderApi api = (Renderable & RenderableFlags.GL) != 0 ? RenderApi.GL : RenderApi.ES;
|
||||
Debug.Print("[EGL] Binding {0} rendering API.", api);
|
||||
if (!Egl.BindAPI(api))
|
||||
{
|
||||
Debug.Print("[EGL] Failed to bind rendering API. Error: {0}", Egl.GetError());
|
||||
}
|
||||
|
||||
bool offscreen = (flags & GraphicsContextFlags.Offscreen) != 0;
|
||||
|
||||
SurfaceType surfaceType = offscreen
|
||||
? SurfaceType.PBUFFER_BIT
|
||||
: SurfaceType.WINDOW_BIT;
|
||||
|
||||
Mode = new EglGraphicsMode().SelectGraphicsMode(surfaceType,
|
||||
window.Display, mode.ColorFormat, mode.Depth, mode.Stencil,
|
||||
mode.Samples, mode.AccumulatorFormat, mode.Buffers, mode.Stereo,
|
||||
Renderable);
|
||||
|
||||
if (!Mode.Index.HasValue)
|
||||
{
|
||||
throw new GraphicsModeException("Invalid or unsupported GraphicsMode.");
|
||||
}
|
||||
IntPtr config = Mode.Index.Value;
|
||||
|
||||
if (window.Surface == IntPtr.Zero)
|
||||
{
|
||||
if (!offscreen)
|
||||
{
|
||||
window.CreateWindowSurface(config);
|
||||
}
|
||||
else
|
||||
{
|
||||
window.CreatePbufferSurface(config);
|
||||
}
|
||||
}
|
||||
|
||||
int[] attribList = { Egl.CONTEXT_CLIENT_VERSION, major, Egl.NONE };
|
||||
var shareContext = shared?.HandleAsEGLContext ?? IntPtr.Zero;
|
||||
HandleAsEGLContext = Egl.CreateContext(window.Display, config, shareContext, attribList);
|
||||
|
||||
GraphicsContextFlags = flags;
|
||||
}
|
||||
|
||||
public EglContext(ContextHandle handle, EglWindowInfo window, IGraphicsContext sharedContext,
|
||||
int major, int minor, GraphicsContextFlags flags)
|
||||
{
|
||||
if (handle == ContextHandle.Zero)
|
||||
{
|
||||
throw new ArgumentException("handle");
|
||||
}
|
||||
if (window == null)
|
||||
{
|
||||
throw new ArgumentNullException("window");
|
||||
}
|
||||
|
||||
Handle = handle;
|
||||
}
|
||||
|
||||
public override void SwapBuffers()
|
||||
{
|
||||
if (!Egl.SwapBuffers(WindowInfo.Display, WindowInfo.Surface))
|
||||
{
|
||||
throw new GraphicsContextException(string.Format("Failed to swap buffers for context {0} current. Error: {1}", Handle, Egl.GetError()));
|
||||
}
|
||||
}
|
||||
|
||||
public override void MakeCurrent(IWindowInfo window)
|
||||
{
|
||||
// Ignore 'window', unless it actually is an EGL window. In other words,
|
||||
// trying to make the EglContext current on a non-EGL window will do,
|
||||
// nothing (the EglContext will remain current on the previous EGL window
|
||||
// or the window it was constructed on (which may not be EGL)).
|
||||
if (window != null)
|
||||
{
|
||||
if (window is EglWindowInfo)
|
||||
{
|
||||
WindowInfo = (EglWindowInfo)window;
|
||||
}
|
||||
else if (window is IAngleWindowInfoInternal)
|
||||
{
|
||||
WindowInfo = ((IAngleWindowInfoInternal)window).EglWindowInfo;
|
||||
}
|
||||
if (!Egl.MakeCurrent(WindowInfo.Display, WindowInfo.Surface, WindowInfo.Surface, HandleAsEGLContext))
|
||||
{
|
||||
throw new GraphicsContextException(string.Format("Failed to make context {0} current. Error: {1}", Handle, Egl.GetError()));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Egl.MakeCurrent(WindowInfo.Display, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsCurrent
|
||||
{
|
||||
get { return Egl.GetCurrentContext() == HandleAsEGLContext; }
|
||||
}
|
||||
|
||||
public override int SwapInterval
|
||||
{
|
||||
get
|
||||
{
|
||||
// Egl.GetSwapInterval does not exist, so store and return the current interval.
|
||||
// The default interval is defined as 1 (true).
|
||||
return swap_interval;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value < 0)
|
||||
{
|
||||
// EGL does not offer EXT_swap_control_tear yet
|
||||
value = 1;
|
||||
}
|
||||
|
||||
if (Egl.SwapInterval(WindowInfo.Display, value))
|
||||
{
|
||||
swap_interval = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Print("[Warning] Egl.SwapInterval({0}, {1}) failed. Error: {2}",
|
||||
WindowInfo.Display, value, Egl.GetError());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update(IWindowInfo window)
|
||||
{
|
||||
MakeCurrent(window);
|
||||
// ANGLE updates the width and height of the back buffer surfaces in the WaitClient function.
|
||||
// So without this calling this function, the surface won't match the size of the window after it
|
||||
// was resized.
|
||||
// https://bugs.chromium.org/p/angleproject/issues/detail?id=1438
|
||||
if (!Egl.WaitClient())
|
||||
{
|
||||
Debug.Print("[Warning] Egl.WaitClient() failed. Error: {0}", Egl.GetError());
|
||||
}
|
||||
}
|
||||
|
||||
public override IntPtr GetAddress(IntPtr function)
|
||||
{
|
||||
// Try loading a static export from ES1 or ES2
|
||||
IntPtr address = GetStaticAddress(function, Renderable);
|
||||
|
||||
// If a static export is not available, try retrieving an extension
|
||||
// function pointer with eglGetProcAddress
|
||||
if (address == IntPtr.Zero)
|
||||
{
|
||||
address = Egl.GetProcAddress(function);
|
||||
}
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
protected abstract IntPtr GetStaticAddress(IntPtr function, RenderableFlags renderable);
|
||||
|
||||
// Todo: cross-reference the specs. What should happen if the context is destroyed from a different
|
||||
// thread?
|
||||
protected override void Dispose(bool manual)
|
||||
{
|
||||
if (!IsDisposed)
|
||||
{
|
||||
if (manual)
|
||||
{
|
||||
if (IsCurrent)
|
||||
{
|
||||
Egl.MakeCurrent(WindowInfo.Display, WindowInfo.Surface, WindowInfo.Surface, IntPtr.Zero);
|
||||
}
|
||||
Egl.DestroyContext(WindowInfo.Display, HandleAsEGLContext);
|
||||
}
|
||||
IsDisposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
private EglContext GetSharedEglContext(IGraphicsContext sharedContext)
|
||||
{
|
||||
if (sharedContext == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var internalContext = sharedContext as IGraphicsContextInternal;
|
||||
if (internalContext != null)
|
||||
{
|
||||
return (EglContext)internalContext.Implementation;
|
||||
}
|
||||
return (EglContext)sharedContext;
|
||||
}
|
||||
}
|
||||
}
|
23
GLWidget/OpenTK/Platform/Egl/EglException.cs
Normal file
23
GLWidget/OpenTK/Platform/Egl/EglException.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
// Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
|
||||
// This file is distributed under GPL v3. See LICENSE.md for details.
|
||||
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace OpenTK.Platform.Egl
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an Egl exception.
|
||||
/// </summary>
|
||||
public class EglException : GraphicsContextException
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the EGL error code.
|
||||
/// </summary>
|
||||
public ErrorCode ErrorCode { get; private set; }
|
||||
|
||||
internal EglException(string message, ErrorCode errorCode) : base(message)
|
||||
{
|
||||
ErrorCode = errorCode;
|
||||
}
|
||||
}
|
||||
}
|
101
GLWidget/OpenTK/Platform/Egl/EglGraphicsMode.cs
Normal file
101
GLWidget/OpenTK/Platform/Egl/EglGraphicsMode.cs
Normal file
|
@ -0,0 +1,101 @@
|
|||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2009 the Open Toolkit library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace OpenTK.Platform.Egl
|
||||
{
|
||||
internal class EglGraphicsMode
|
||||
{
|
||||
public GraphicsMode SelectGraphicsMode(EglWindowInfo window,
|
||||
GraphicsMode mode, RenderableFlags flags)
|
||||
{
|
||||
return SelectGraphicsMode(window,
|
||||
mode.ColorFormat, mode.Depth, mode.Stencil,
|
||||
mode.Samples, mode.AccumulatorFormat, mode.Buffers, mode.Stereo,
|
||||
flags);
|
||||
}
|
||||
|
||||
public GraphicsMode SelectGraphicsMode(EglWindowInfo window,
|
||||
ColorFormat color, int depth, int stencil,
|
||||
int samples, ColorFormat accum, int buffers, bool stereo,
|
||||
RenderableFlags renderableFlags)
|
||||
{
|
||||
return SelectGraphicsMode(
|
||||
SurfaceType.WINDOW_BIT,
|
||||
window.Display,
|
||||
color, depth, stencil, samples, accum, buffers, stereo, renderableFlags);
|
||||
}
|
||||
|
||||
public GraphicsMode SelectGraphicsMode(SurfaceType surfaceType,
|
||||
IntPtr display, ColorFormat color, int depth, int stencil,
|
||||
int samples, ColorFormat accum, int buffers, bool stereo,
|
||||
RenderableFlags renderableFlags)
|
||||
{
|
||||
IntPtr[] configs = new IntPtr[1];
|
||||
int[] attribList = new int[]
|
||||
{
|
||||
Egl.SURFACE_TYPE, (int)surfaceType,
|
||||
Egl.RENDERABLE_TYPE, (int)renderableFlags,
|
||||
|
||||
Egl.RED_SIZE, color.Red,
|
||||
Egl.GREEN_SIZE, color.Green,
|
||||
Egl.BLUE_SIZE, color.Blue,
|
||||
Egl.ALPHA_SIZE, color.Alpha,
|
||||
|
||||
Egl.DEPTH_SIZE, depth > 0 ? depth : 0,
|
||||
Egl.STENCIL_SIZE, stencil > 0 ? stencil : 0,
|
||||
|
||||
Egl.SAMPLE_BUFFERS, samples > 0 ? 1 : 0,
|
||||
Egl.SAMPLES, samples > 0 ? samples : 0,
|
||||
|
||||
Egl.NONE,
|
||||
};
|
||||
|
||||
int numConfigs;
|
||||
if (!Egl.ChooseConfig(display, attribList, configs, configs.Length, out numConfigs) || numConfigs == 0)
|
||||
{
|
||||
throw new GraphicsModeException(String.Format("Failed to retrieve GraphicsMode, error {0}", Egl.GetError()));
|
||||
}
|
||||
|
||||
// See what we really got
|
||||
IntPtr activeConfig = configs[0];
|
||||
int r, g, b, a;
|
||||
Egl.GetConfigAttrib(display, activeConfig, Egl.RED_SIZE, out r);
|
||||
Egl.GetConfigAttrib(display, activeConfig, Egl.GREEN_SIZE, out g);
|
||||
Egl.GetConfigAttrib(display, activeConfig, Egl.BLUE_SIZE, out b);
|
||||
Egl.GetConfigAttrib(display, activeConfig, Egl.ALPHA_SIZE, out a);
|
||||
int d, s;
|
||||
Egl.GetConfigAttrib(display, activeConfig, Egl.DEPTH_SIZE, out d);
|
||||
Egl.GetConfigAttrib(display, activeConfig, Egl.STENCIL_SIZE, out s);
|
||||
int sampleBuffers;
|
||||
Egl.GetConfigAttrib(display, activeConfig, Egl.SAMPLES, out sampleBuffers);
|
||||
Egl.GetConfigAttrib(display, activeConfig, Egl.SAMPLES, out samples);
|
||||
|
||||
return new GraphicsMode(activeConfig, new ColorFormat(r, g, b, a), d, s, sampleBuffers > 0 ? samples : 0, 0, 2, false);
|
||||
}
|
||||
}
|
||||
}
|
44
GLWidget/OpenTK/Platform/Egl/EglMacPlatformFactory.cs
Normal file
44
GLWidget/OpenTK/Platform/Egl/EglMacPlatformFactory.cs
Normal file
|
@ -0,0 +1,44 @@
|
|||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2009 the Open Toolkit library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using OpenTK.Graphics;
|
||||
using OpenTK.Platform.MacOS;
|
||||
|
||||
namespace OpenTK.Platform.Egl
|
||||
{
|
||||
internal class EglMacPlatformFactory : MacOSFactory
|
||||
{
|
||||
public override IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override IGraphicsContext CreateGLContext(ContextHandle handle, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
135
GLWidget/OpenTK/Platform/Egl/EglUnixContext.cs
Normal file
135
GLWidget/OpenTK/Platform/Egl/EglUnixContext.cs
Normal file
|
@ -0,0 +1,135 @@
|
|||
//
|
||||
// EglUnixContext.cs
|
||||
//
|
||||
// Author:
|
||||
// Stefanos A. <stapostol@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2006-2014 Stefanos Apostolopoulos
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace OpenTK.Platform.Egl
|
||||
{
|
||||
internal class EglUnixContext : EglContext
|
||||
{
|
||||
private IntPtr ES1 = OpenTK.Platform.X11.DL.Open("libGLESv1_CM", X11.DLOpenFlags.Lazy);
|
||||
private IntPtr ES2 = OpenTK.Platform.X11.DL.Open("libGLESv2", X11.DLOpenFlags.Lazy);
|
||||
private IntPtr GL = OpenTK.Platform.X11.DL.Open("libGL", X11.DLOpenFlags.Lazy);
|
||||
|
||||
public EglUnixContext(GraphicsMode mode, EglWindowInfo window, IGraphicsContext sharedContext,
|
||||
int major, int minor, GraphicsContextFlags flags)
|
||||
: base(mode, window, sharedContext, major, minor, flags)
|
||||
{
|
||||
}
|
||||
|
||||
public EglUnixContext(ContextHandle handle, EglWindowInfo window, IGraphicsContext sharedContext,
|
||||
int major, int minor, GraphicsContextFlags flags)
|
||||
: base(handle, window, sharedContext, major, minor, flags)
|
||||
{
|
||||
}
|
||||
|
||||
protected override IntPtr GetStaticAddress(IntPtr function, RenderableFlags renderable)
|
||||
{
|
||||
if ((renderable & (RenderableFlags.ES2 | RenderableFlags.ES3)) != 0 && ES2 != IntPtr.Zero)
|
||||
{
|
||||
return X11.DL.Symbol(ES2, function);
|
||||
}
|
||||
else if ((renderable & RenderableFlags.ES) != 0 && ES1 != IntPtr.Zero)
|
||||
{
|
||||
return X11.DL.Symbol(ES1, function);
|
||||
}
|
||||
else if ((renderable & RenderableFlags.GL) != 0 && GL != IntPtr.Zero)
|
||||
{
|
||||
return X11.DL.Symbol(GL, function);
|
||||
}
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool manual)
|
||||
{
|
||||
if (ES1 != IntPtr.Zero)
|
||||
{
|
||||
X11.DL.Close(ES1);
|
||||
}
|
||||
if (ES2 != IntPtr.Zero)
|
||||
{
|
||||
X11.DL.Close(ES2);
|
||||
}
|
||||
if (GL != IntPtr.Zero)
|
||||
{
|
||||
X11.DL.Close(GL);
|
||||
}
|
||||
|
||||
GL = ES1 = ES2 = IntPtr.Zero;
|
||||
|
||||
base.Dispose(manual);
|
||||
}
|
||||
|
||||
public override void LoadAll()
|
||||
{
|
||||
// Modern unices can use EGL to create
|
||||
// both GL and ES contexts, so we need
|
||||
// to load all entry points. This is
|
||||
// especially true on KMS, Wayland and Mir.
|
||||
|
||||
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");
|
||||
|
||||
Debug.Print("Bindings loaded in {0} ms.", time.Elapsed.TotalMilliseconds);
|
||||
}
|
||||
}
|
||||
}
|
79
GLWidget/OpenTK/Platform/Egl/EglWinContext.cs
Normal file
79
GLWidget/OpenTK/Platform/Egl/EglWinContext.cs
Normal file
|
@ -0,0 +1,79 @@
|
|||
//
|
||||
// EglWinContext.cs
|
||||
//
|
||||
// Author:
|
||||
// Stefanos A. <stapostol@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2006-2014 Stefanos Apostolopoulos
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace OpenTK.Platform.Egl
|
||||
{
|
||||
internal class EglWinContext : EglContext
|
||||
{
|
||||
private IntPtr ES1 = OpenTK.Platform.Windows.Functions.LoadLibrary("libGLESv1_CM");
|
||||
private IntPtr ES2 = OpenTK.Platform.Windows.Functions.LoadLibrary("libGLESv2");
|
||||
|
||||
public EglWinContext(GraphicsMode mode, EglWindowInfo window, IGraphicsContext sharedContext,
|
||||
int major, int minor, GraphicsContextFlags flags)
|
||||
: base(mode, window, sharedContext, major, minor, flags)
|
||||
{
|
||||
}
|
||||
|
||||
public EglWinContext(ContextHandle handle, EglWindowInfo window, IGraphicsContext sharedContext,
|
||||
int major, int minor, GraphicsContextFlags flags)
|
||||
: base(handle, window, sharedContext, major, minor, flags)
|
||||
{
|
||||
}
|
||||
|
||||
protected override IntPtr GetStaticAddress(IntPtr function, RenderableFlags renderable)
|
||||
{
|
||||
if ((renderable & (RenderableFlags.ES2 | RenderableFlags.ES3)) != 0 && ES2 != IntPtr.Zero)
|
||||
{
|
||||
return Windows.Functions.GetProcAddress(ES2, function);
|
||||
}
|
||||
else if ((renderable & RenderableFlags.ES) != 0 && ES1 != IntPtr.Zero)
|
||||
{
|
||||
return Windows.Functions.GetProcAddress(ES1, function);
|
||||
}
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool manual)
|
||||
{
|
||||
if (ES1 != IntPtr.Zero)
|
||||
{
|
||||
Windows.Functions.FreeLibrary(ES1);
|
||||
}
|
||||
if (ES2 != IntPtr.Zero)
|
||||
{
|
||||
Windows.Functions.FreeLibrary(ES2);
|
||||
}
|
||||
|
||||
ES1 = ES2 = IntPtr.Zero;
|
||||
|
||||
base.Dispose(manual);
|
||||
}
|
||||
}
|
||||
}
|
70
GLWidget/OpenTK/Platform/Egl/EglWinPlatformFactory.cs
Normal file
70
GLWidget/OpenTK/Platform/Egl/EglWinPlatformFactory.cs
Normal file
|
@ -0,0 +1,70 @@
|
|||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2009 the Open Toolkit library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using OpenTK.Graphics;
|
||||
using OpenTK.Platform.Windows;
|
||||
|
||||
namespace OpenTK.Platform.Egl
|
||||
{
|
||||
// EGL factory for the Windows platform.
|
||||
internal class EglWinPlatformFactory : WinFactory
|
||||
{
|
||||
public override IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
|
||||
{
|
||||
WinWindowInfo win_win = (WinWindowInfo)window;
|
||||
IntPtr egl_display = GetDisplay(win_win.DeviceContext);
|
||||
EglWindowInfo egl_win = new OpenTK.Platform.Egl.EglWindowInfo(win_win.Handle, egl_display);
|
||||
return new EglWinContext(mode, egl_win, shareContext, major, minor, flags);
|
||||
}
|
||||
|
||||
public override IGraphicsContext CreateGLContext(ContextHandle handle, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
|
||||
{
|
||||
WinWindowInfo win_win = (WinWindowInfo)window;
|
||||
IntPtr egl_display = GetDisplay(win_win.DeviceContext);
|
||||
EglWindowInfo egl_win = new OpenTK.Platform.Egl.EglWindowInfo(win_win.Handle, egl_display);
|
||||
return new EglWinContext(handle, egl_win, shareContext, major, minor, flags);
|
||||
}
|
||||
|
||||
public override GraphicsContext.GetCurrentContextDelegate CreateGetCurrentGraphicsContext()
|
||||
{
|
||||
return (GraphicsContext.GetCurrentContextDelegate)delegate
|
||||
{
|
||||
return new ContextHandle(Egl.GetCurrentContext());
|
||||
};
|
||||
}
|
||||
|
||||
private IntPtr GetDisplay(IntPtr dc)
|
||||
{
|
||||
IntPtr display = Egl.GetDisplay(dc);
|
||||
if (display == IntPtr.Zero)
|
||||
{
|
||||
display = Egl.GetDisplay(IntPtr.Zero);
|
||||
}
|
||||
|
||||
return display;
|
||||
}
|
||||
}
|
||||
}
|
186
GLWidget/OpenTK/Platform/Egl/EglWindowInfo.cs
Normal file
186
GLWidget/OpenTK/Platform/Egl/EglWindowInfo.cs
Normal file
|
@ -0,0 +1,186 @@
|
|||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2009 the Open Toolkit library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace OpenTK.Platform.Egl
|
||||
{
|
||||
// Holds information about an EGL window.
|
||||
internal class EglWindowInfo : IWindowInfo
|
||||
{
|
||||
private IntPtr surface;
|
||||
private bool disposed;
|
||||
|
||||
public EglWindowInfo(IntPtr handle, IntPtr display)
|
||||
: this(handle, display, IntPtr.Zero)
|
||||
{
|
||||
}
|
||||
|
||||
public EglWindowInfo(IntPtr handle, IntPtr display, IntPtr surface)
|
||||
{
|
||||
Handle = handle;
|
||||
Surface = surface;
|
||||
|
||||
if (display == IntPtr.Zero)
|
||||
{
|
||||
display = Egl.GetDisplay(IntPtr.Zero);
|
||||
}
|
||||
|
||||
Display = display;
|
||||
|
||||
int dummyMajor, dummyMinor;
|
||||
if (!Egl.Initialize(Display, out dummyMajor, out dummyMinor))
|
||||
{
|
||||
throw new GraphicsContextException(String.Format("Failed to initialize EGL, error {0}.", Egl.GetError()));
|
||||
}
|
||||
}
|
||||
|
||||
public IntPtr Handle { get; set; }
|
||||
|
||||
public IntPtr Display { get; private set; }
|
||||
|
||||
public IntPtr Surface { get { return surface; } private set { surface = value; } }
|
||||
|
||||
public void CreateWindowSurface(IntPtr config)
|
||||
{
|
||||
Surface = Egl.CreateWindowSurface(Display, config, Handle, IntPtr.Zero);
|
||||
if (Surface == IntPtr.Zero)
|
||||
{
|
||||
throw new GraphicsContextException(String.Format(
|
||||
"[EGL] Failed to create window surface, error {0}.", Egl.GetError()));
|
||||
}
|
||||
}
|
||||
|
||||
//public void CreatePixmapSurface(EGLConfig config)
|
||||
//{
|
||||
// Surface = Egl.CreatePixmapSurface(Display, config, Handle, null);
|
||||
//}
|
||||
|
||||
public void CreatePbufferSurface(IntPtr config)
|
||||
{
|
||||
int[] attribs = new int[]{Egl.NONE};
|
||||
Surface = Egl.CreatePbufferSurface(Display, config, attribs);
|
||||
if (Surface == IntPtr.Zero)
|
||||
{
|
||||
throw new GraphicsContextException(String.Format(
|
||||
"[EGL] Failed to create pbuffer surface, error {0}.", Egl.GetError()));
|
||||
}
|
||||
}
|
||||
|
||||
public void CreatePbufferSurface(IntPtr config, int width, int height)
|
||||
{
|
||||
if (surface != IntPtr.Zero)
|
||||
{
|
||||
DestroySurface();
|
||||
}
|
||||
CreatePbufferSurface(config, width, height, out surface);
|
||||
}
|
||||
|
||||
public void CreatePbufferSurface(IntPtr config, int width, int height, out IntPtr bufferSurface)
|
||||
{
|
||||
int[] attribs = new int[]
|
||||
{
|
||||
Egl.WIDTH, width,
|
||||
Egl.HEIGHT, height,
|
||||
Egl.TEXTURE_TARGET, Egl.TEXTURE_2D,
|
||||
Egl.TEXTURE_FORMAT, Egl.TEXTURE_RGBA,
|
||||
Egl.NONE
|
||||
};
|
||||
bufferSurface = Egl.CreatePbufferSurface(Display, config, attribs);
|
||||
if (bufferSurface == IntPtr.Zero)
|
||||
{
|
||||
throw new GraphicsContextException(String.Format(
|
||||
"[EGL] Failed to create pbuffer surface, error {0}.", Egl.GetError()));
|
||||
}
|
||||
}
|
||||
|
||||
public void DestroySurface()
|
||||
{
|
||||
DestroySurface(ref surface);
|
||||
}
|
||||
|
||||
public void DestroySurface(ref IntPtr bufferSurface)
|
||||
{
|
||||
if (bufferSurface == IntPtr.Zero)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Egl.GetCurrentSurface(Egl.DRAW) == Surface)
|
||||
{
|
||||
Egl.MakeCurrent(Display, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
|
||||
}
|
||||
if (Egl.DestroySurface(Display, bufferSurface))
|
||||
{
|
||||
bufferSurface = IntPtr.Zero;
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Print("[Warning] Failed to destroy {0}:{1}.", Surface.GetType().Name, Surface);
|
||||
Surface = IntPtr.Zero;
|
||||
}
|
||||
|
||||
public void TerminateDisplay()
|
||||
{
|
||||
if (Display != IntPtr.Zero)
|
||||
{
|
||||
if (!Egl.Terminate(Display))
|
||||
{
|
||||
Debug.Print("[Warning] Failed to terminate display {0}.", Display);
|
||||
}
|
||||
Display = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
private void Dispose(bool manual)
|
||||
{
|
||||
if (!disposed)
|
||||
{
|
||||
if (manual)
|
||||
{
|
||||
DestroySurface();
|
||||
disposed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Print("[Warning] Failed to destroy {0}:{1}.", this.GetType().Name, Handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~EglWindowInfo()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
}
|
||||
}
|
55
GLWidget/OpenTK/Platform/Egl/EglX11PlatformFactory.cs
Normal file
55
GLWidget/OpenTK/Platform/Egl/EglX11PlatformFactory.cs
Normal file
|
@ -0,0 +1,55 @@
|
|||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2009 the Open Toolkit library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using OpenTK.Graphics;
|
||||
using OpenTK.Platform.X11;
|
||||
|
||||
namespace OpenTK.Platform.Egl
|
||||
{
|
||||
internal class EglX11PlatformFactory : X11Factory
|
||||
{
|
||||
public override IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
|
||||
{
|
||||
X11WindowInfo x11_win = (X11WindowInfo)window;
|
||||
EglWindowInfo egl_win = new OpenTK.Platform.Egl.EglWindowInfo(x11_win.Handle, Egl.GetDisplay(x11_win.Display));
|
||||
return new EglUnixContext(mode, egl_win, shareContext, major, minor, flags);
|
||||
}
|
||||
|
||||
public override IGraphicsContext CreateGLContext(ContextHandle handle, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
|
||||
{
|
||||
X11WindowInfo x11_win = (X11WindowInfo)window;
|
||||
EglWindowInfo egl_win = new OpenTK.Platform.Egl.EglWindowInfo(x11_win.Handle, Egl.GetDisplay(x11_win.Display));
|
||||
return new EglUnixContext(handle, egl_win, shareContext, major, minor, flags);
|
||||
}
|
||||
|
||||
public override GraphicsContext.GetCurrentContextDelegate CreateGetCurrentGraphicsContext()
|
||||
{
|
||||
return (GraphicsContext.GetCurrentContextDelegate)delegate
|
||||
{
|
||||
return new ContextHandle(Egl.GetCurrentContext());
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
78
GLWidget/OpenTK/Platform/EmbeddedGraphicsContext.cs
Normal file
78
GLWidget/OpenTK/Platform/EmbeddedGraphicsContext.cs
Normal file
|
@ -0,0 +1,78 @@
|
|||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2009 the Open Toolkit library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace OpenTK.Platform
|
||||
{
|
||||
// Provides the foundation for all desktop IGraphicsContext implementations.
|
||||
internal abstract class EmbeddedGraphicsContext : GraphicsContextBase
|
||||
{
|
||||
public override void LoadAll()
|
||||
{
|
||||
// Modern unices can use EGL to create
|
||||
// both GL and ES contexts, so we need
|
||||
// to load all entry points. This is
|
||||
// especially true on KMS, Wayland and Mir.
|
||||
|
||||
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");
|
||||
|
||||
Debug.Print("Bindings loaded in {0} ms.", time.Elapsed.TotalMilliseconds);
|
||||
}
|
||||
}
|
||||
}
|
192
GLWidget/OpenTK/Platform/Factory.cs
Normal file
192
GLWidget/OpenTK/Platform/Factory.cs
Normal file
|
@ -0,0 +1,192 @@
|
|||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2009 the Open Toolkit library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace OpenTK.Platform
|
||||
{
|
||||
using Graphics;
|
||||
|
||||
internal sealed class Factory : IPlatformFactory
|
||||
{
|
||||
private bool disposed;
|
||||
|
||||
static Factory()
|
||||
{
|
||||
Toolkit.Init();
|
||||
}
|
||||
|
||||
public Factory()
|
||||
{
|
||||
// Ensure we are correctly initialized.
|
||||
Toolkit.Init();
|
||||
|
||||
// Create regular platform backend
|
||||
if (Configuration.RunningOnWindows)
|
||||
{
|
||||
Default = new Windows.WinFactory();
|
||||
}
|
||||
else if (Configuration.RunningOnMacOS)
|
||||
{
|
||||
Default = new MacOS.MacOSFactory();
|
||||
}
|
||||
else if (Configuration.RunningOnX11)
|
||||
{
|
||||
Default = new X11.X11Factory();
|
||||
}
|
||||
else if (Configuration.RunningOnLinux)
|
||||
{
|
||||
Default = new Linux.LinuxFactory();
|
||||
}
|
||||
if (Default == null)
|
||||
{
|
||||
Default = new UnsupportedPlatform();
|
||||
}
|
||||
|
||||
if (Egl.Egl.IsSupported)
|
||||
{
|
||||
if (Configuration.RunningOnLinux)
|
||||
{
|
||||
Embedded = Default;
|
||||
}
|
||||
else if (Configuration.RunningOnX11)
|
||||
{
|
||||
Embedded = new Egl.EglX11PlatformFactory();
|
||||
}
|
||||
else if (Configuration.RunningOnWindows)
|
||||
{
|
||||
Embedded = new Egl.EglWinPlatformFactory();
|
||||
}
|
||||
else if (Configuration.RunningOnMacOS)
|
||||
{
|
||||
Embedded = new Egl.EglMacPlatformFactory();
|
||||
}
|
||||
else
|
||||
{
|
||||
Embedded = new UnsupportedPlatform();
|
||||
}
|
||||
Angle = new Egl.EglAnglePlatformFactory(Embedded);
|
||||
}
|
||||
else
|
||||
{
|
||||
Embedded = new UnsupportedPlatform();
|
||||
Angle = Embedded;
|
||||
}
|
||||
|
||||
if (Default is UnsupportedPlatform && !(Embedded is UnsupportedPlatform))
|
||||
{
|
||||
Default = Embedded;
|
||||
}
|
||||
}
|
||||
|
||||
public static IPlatformFactory Default { get; private set; }
|
||||
|
||||
public static IPlatformFactory Embedded { get; private set; }
|
||||
|
||||
public static IPlatformFactory Angle { get; private set; }
|
||||
|
||||
public IDisplayDeviceDriver CreateDisplayDeviceDriver()
|
||||
{
|
||||
return Default.CreateDisplayDeviceDriver();
|
||||
}
|
||||
|
||||
public IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
|
||||
{
|
||||
return Default.CreateGLContext(mode, window, shareContext, directRendering, major, minor, flags);
|
||||
}
|
||||
|
||||
public IGraphicsContext CreateGLContext(ContextHandle handle, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
|
||||
{
|
||||
return Default.CreateGLContext(handle, window, shareContext, directRendering, major, minor, flags);
|
||||
}
|
||||
|
||||
public GraphicsContext.GetCurrentContextDelegate CreateGetCurrentGraphicsContext()
|
||||
{
|
||||
return Default.CreateGetCurrentGraphicsContext();
|
||||
}
|
||||
|
||||
public void RegisterResource(IDisposable resource)
|
||||
{
|
||||
Default.RegisterResource(resource);
|
||||
}
|
||||
|
||||
private class UnsupportedPlatform : PlatformFactoryBase
|
||||
{
|
||||
private static readonly string error_string = "Please, refer to http://www.opentk.com for more information.";
|
||||
|
||||
public override IDisplayDeviceDriver CreateDisplayDeviceDriver()
|
||||
{
|
||||
throw new PlatformNotSupportedException(error_string);
|
||||
}
|
||||
|
||||
public override IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
|
||||
{
|
||||
throw new PlatformNotSupportedException(error_string);
|
||||
}
|
||||
|
||||
public override IGraphicsContext CreateGLContext(ContextHandle handle, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
|
||||
{
|
||||
throw new PlatformNotSupportedException(error_string);
|
||||
}
|
||||
|
||||
public override GraphicsContext.GetCurrentContextDelegate CreateGetCurrentGraphicsContext()
|
||||
{
|
||||
throw new PlatformNotSupportedException(error_string);
|
||||
}
|
||||
}
|
||||
|
||||
private void Dispose(bool manual)
|
||||
{
|
||||
if (!disposed)
|
||||
{
|
||||
if (manual)
|
||||
{
|
||||
Default.Dispose();
|
||||
if (Embedded != Default)
|
||||
{
|
||||
Embedded.Dispose();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Print("{0} leaked, did you forget to call Dispose()?", GetType());
|
||||
}
|
||||
disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
~Factory()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
}
|
||||
}
|
34
GLWidget/OpenTK/Platform/IDisplayDeviceDriver.cs
Normal file
34
GLWidget/OpenTK/Platform/IDisplayDeviceDriver.cs
Normal file
|
@ -0,0 +1,34 @@
|
|||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2010 the Open Toolkit library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
namespace OpenTK.Platform
|
||||
{
|
||||
internal interface IDisplayDeviceDriver
|
||||
{
|
||||
bool TryChangeResolution(DisplayDevice device, DisplayResolution resolution);
|
||||
bool TryRestoreResolution(DisplayDevice device);
|
||||
DisplayDevice GetDisplay(DisplayIndex displayIndex);
|
||||
}
|
||||
}
|
43
GLWidget/OpenTK/Platform/IPlatformFactory.cs
Normal file
43
GLWidget/OpenTK/Platform/IPlatformFactory.cs
Normal file
|
@ -0,0 +1,43 @@
|
|||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2009 the Open Toolkit library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace OpenTK.Platform
|
||||
{
|
||||
internal interface IPlatformFactory : IDisposable
|
||||
{
|
||||
IDisplayDeviceDriver CreateDisplayDeviceDriver();
|
||||
|
||||
IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags);
|
||||
|
||||
IGraphicsContext CreateGLContext(ContextHandle handle, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags);
|
||||
|
||||
GraphicsContext.GetCurrentContextDelegate CreateGetCurrentGraphicsContext();
|
||||
|
||||
void RegisterResource(IDisposable resource);
|
||||
}
|
||||
}
|
19
GLWidget/OpenTK/Platform/IWindowInfo.cs
Normal file
19
GLWidget/OpenTK/Platform/IWindowInfo.cs
Normal file
|
@ -0,0 +1,19 @@
|
|||
/* Licensed under the MIT/X11 license.
|
||||
* Copyright (c) 2006-2008 the OpenTK Team.
|
||||
* This notice may not be removed from any source distribution.
|
||||
* See license.txt for licensing detailed licensing details.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace OpenTK.Platform
|
||||
{
|
||||
/// <summary>Describes an OS window.</summary>
|
||||
public interface IWindowInfo : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieves a platform-specific handle to this window.
|
||||
/// </summary>
|
||||
IntPtr Handle { get; }
|
||||
}
|
||||
}
|
209
GLWidget/OpenTK/Platform/Linux/Bindings/Drm.cs
Normal file
209
GLWidget/OpenTK/Platform/Linux/Bindings/Drm.cs
Normal file
|
@ -0,0 +1,209 @@
|
|||
//
|
||||
// Drm.cs
|
||||
//
|
||||
// Author:
|
||||
// Stefanos A. <stapostol@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2006-2014 Stefanos Apostolopoulos
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
#pragma warning disable 0649 // field is never assigned
|
||||
|
||||
namespace OpenTK.Platform.Linux
|
||||
{
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
internal delegate void VBlankCallback(int fd,
|
||||
int sequence,
|
||||
int tv_sec,
|
||||
int tv_usec,
|
||||
IntPtr user_data);
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
internal delegate void PageFlipCallback(int fd,
|
||||
int sequence,
|
||||
int tv_sec,
|
||||
int tv_usec,
|
||||
IntPtr user_data);
|
||||
|
||||
internal class Drm
|
||||
{
|
||||
private const string lib = "libdrm";
|
||||
|
||||
[DllImport(lib, EntryPoint = "drmHandleEvent", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int HandleEvent(int fd, ref EventContext evctx);
|
||||
|
||||
[DllImport(lib, EntryPoint = "drmModeAddFB", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int ModeAddFB(int fd, int width, int height, byte depth,
|
||||
byte bpp, int pitch, int bo_handle,
|
||||
out int buf_id);
|
||||
|
||||
[DllImport(lib, EntryPoint = "drmModeRmFB", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int ModeRmFB(int fd, int bufferId);
|
||||
|
||||
[DllImport(lib, EntryPoint = "drmModeFreeCrtc", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void ModeFreeCrtc(IntPtr ptr);
|
||||
|
||||
[DllImport(lib, EntryPoint = "drmModeGetCrtc", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr ModeGetCrtc(int fd, int crtcId);
|
||||
|
||||
[DllImport(lib, EntryPoint = "drmModeFreeConnector", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void ModeFreeConnector(IntPtr ptr);
|
||||
|
||||
[DllImport(lib, EntryPoint = "drmModeFreeEncoder", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void ModeFreeEncoder(IntPtr ptr);
|
||||
|
||||
[DllImport(lib, EntryPoint = "drmModeGetConnector", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr ModeGetConnector(int fd, int connector_id);
|
||||
|
||||
[DllImport(lib, EntryPoint = "drmModeGetEncoder", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr ModeGetEncoder(int fd, int encoder_id);
|
||||
|
||||
[DllImport(lib, EntryPoint = "drmModeGetResources", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr ModeGetResources(int fd);
|
||||
|
||||
[DllImport(lib, EntryPoint = "drmModePageFlip", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int ModePageFlip(int fd, int crtc_id, int fb_id,
|
||||
PageFlipFlags flags, IntPtr user_data);
|
||||
|
||||
[DllImport(lib, EntryPoint = "drmModeSetCrtc", CallingConvention = CallingConvention.Cdecl)]
|
||||
unsafe public static extern int ModeSetCrtc(int fd, int crtcId, int bufferId,
|
||||
int x, int y, int* connectors, int count, ModeInfo* mode);
|
||||
|
||||
[DllImport(lib, EntryPoint = "drmModeSetCursor2", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int SetCursor(int fd, int crtcId, int bo_handle, int width, int height, int hot_x, int hot_y);
|
||||
|
||||
[DllImport(lib, EntryPoint = "drmModeMoveCursor", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int MoveCursor(int fd, int crtcId, int x, int y);
|
||||
|
||||
}
|
||||
|
||||
internal enum ModeConnection
|
||||
{
|
||||
Connected = 1,
|
||||
Disconnected = 2,
|
||||
Unknown = 3
|
||||
}
|
||||
|
||||
internal enum ModeSubPixel
|
||||
{
|
||||
Unknown = 1,
|
||||
HorizontalRgb = 2,
|
||||
HorizontalBgr = 3,
|
||||
VerticalRgb = 4,
|
||||
VerticalBgr = 5,
|
||||
None = 6
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum PageFlipFlags
|
||||
{
|
||||
FlipEvent = 0x01,
|
||||
FlipAsync = 0x02,
|
||||
FlipFlags = FlipEvent | FlipAsync
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct EventContext
|
||||
{
|
||||
public int version;
|
||||
public IntPtr vblank_handler;
|
||||
public IntPtr page_flip_handler;
|
||||
|
||||
public static readonly int Version = 2;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal unsafe struct ModeConnector
|
||||
{
|
||||
public int connector_id;
|
||||
public int encoder_id;
|
||||
public int connector_type;
|
||||
public int connector_type_id;
|
||||
public ModeConnection connection;
|
||||
public int mmWidth, mmHeight;
|
||||
public ModeSubPixel subpixel;
|
||||
|
||||
public int count_modes;
|
||||
public ModeInfo* modes;
|
||||
|
||||
public int count_props;
|
||||
public int *props;
|
||||
public long *prop_values;
|
||||
|
||||
public int count_encoders;
|
||||
public int *encoders;
|
||||
}
|
||||
|
||||
internal struct ModeCrtc
|
||||
{
|
||||
public int crtc_id;
|
||||
public int buffer_id;
|
||||
|
||||
public int x, y;
|
||||
public int width, height;
|
||||
public int mode_valid;
|
||||
public ModeInfo mode;
|
||||
|
||||
public int gamma_size;
|
||||
}
|
||||
|
||||
internal struct ModeEncoder
|
||||
{
|
||||
public int encoder_id;
|
||||
public int encoder_type;
|
||||
public int crtc_id;
|
||||
public int possible_crtcs;
|
||||
public int possible_clones;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal unsafe struct ModeInfo
|
||||
{
|
||||
public uint clock;
|
||||
public ushort hdisplay, hsync_start, hsync_end, htotal, hskew;
|
||||
public ushort vdisplay, vsync_start, vsync_end, vtotal, vscan;
|
||||
|
||||
public int vrefresh; // refresh rate * 1000
|
||||
|
||||
public uint flags;
|
||||
public uint type;
|
||||
public fixed sbyte name[32];
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal unsafe struct ModeRes
|
||||
{
|
||||
public int count_fbs;
|
||||
public int* fbs;
|
||||
public int count_crtcs;
|
||||
public int* crtcs;
|
||||
public int count_connectors;
|
||||
public int* connectors;
|
||||
public int count_encoders;
|
||||
public int* encoders;
|
||||
public int min_width, max_width;
|
||||
public int min_height, max_height;
|
||||
}
|
||||
}
|
||||
|
272
GLWidget/OpenTK/Platform/Linux/Bindings/Gbm.cs
Normal file
272
GLWidget/OpenTK/Platform/Linux/Bindings/Gbm.cs
Normal file
|
@ -0,0 +1,272 @@
|
|||
//
|
||||
// Gbm.cs
|
||||
//
|
||||
// Author:
|
||||
// Stefanos A. <stapostol@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2006-2014 Stefanos Apostolopoulos
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OpenTK.Platform.Linux
|
||||
{
|
||||
using Device = IntPtr; // struct gbm_device*
|
||||
using Surface = IntPtr;
|
||||
using BufferObjectHandle = IntPtr;
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
internal delegate void DestroyUserDataCallback(BufferObject bo, IntPtr data);
|
||||
|
||||
internal class Gbm
|
||||
{
|
||||
private const string lib = "gbm";
|
||||
|
||||
[DllImport(lib, EntryPoint = "gbm_bo_create", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern BufferObject CreateBuffer(Device gbm, int width, int height, SurfaceFormat format, SurfaceFlags flags);
|
||||
|
||||
[DllImport(lib, EntryPoint = "gbm_bo_destroy", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void DestroyBuffer(BufferObject bo);
|
||||
|
||||
[DllImport(lib, EntryPoint = "gbm_bo_write", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int BOWrite(IntPtr bo, IntPtr buf, IntPtr count);
|
||||
|
||||
[DllImport(lib, EntryPoint = "gbm_bo_get_device", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern Device BOGetDevice(IntPtr bo);
|
||||
|
||||
[DllImport(lib, EntryPoint = "gbm_bo_get_handle", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern BufferObjectHandle BOGetHandle(IntPtr bo);
|
||||
|
||||
[DllImport(lib, EntryPoint = "gbm_bo_get_height", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int BOGetHeight(IntPtr bo);
|
||||
|
||||
[DllImport(lib, EntryPoint = "gbm_bo_get_width", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int BOGetWidth(IntPtr bo);
|
||||
|
||||
[DllImport(lib, EntryPoint = "gbm_bo_get_stride", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int BOGetStride(IntPtr bo);
|
||||
|
||||
[DllImport(lib, EntryPoint = "gbm_bo_set_user_data", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void BOSetUserData(IntPtr bo, IntPtr data, DestroyUserDataCallback callback);
|
||||
|
||||
[DllImport(lib, EntryPoint = "gbm_create_device", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern Device CreateDevice(int fd);
|
||||
|
||||
[DllImport(lib, EntryPoint = "gbm_device_destroy", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void DestroyDevice(Device gbm);
|
||||
|
||||
[DllImport(lib, EntryPoint = "gbm_device_get_fd", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int DeviceGetFD(IntPtr gbm);
|
||||
|
||||
[DllImport(lib, EntryPoint = "gbm_surface_create", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern Surface CreateSurface(Device gbm, int width, int height, SurfaceFormat format, SurfaceFlags flags);
|
||||
|
||||
[DllImport(lib, EntryPoint = "gbm_surface_destroy", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void DestroySurface(IntPtr surface);
|
||||
|
||||
[DllImport(lib, EntryPoint = "gbm_device_is_format_supported", CallingConvention = CallingConvention.Cdecl)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool IsFormatSupported(Device gbm, SurfaceFormat format, SurfaceFlags usage);
|
||||
|
||||
[DllImport(lib, EntryPoint = "gbm_surface_lock_front_buffer", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern BufferObject LockFrontBuffer(Surface surface);
|
||||
|
||||
[DllImport(lib, EntryPoint = "gbm_surface_release_buffer", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void ReleaseBuffer(Surface surface, BufferObject buffer);
|
||||
}
|
||||
|
||||
internal enum SurfaceFormat
|
||||
{
|
||||
BigEndian = 1 << 31,
|
||||
C8 = ((int)('C') | ((int)('8') << 8) | ((int)(' ') << 16) | ((int)(' ') << 24)),
|
||||
|
||||
RGB332 = ((int)('R') | ((int)('G') << 8) | ((int)('B') << 16) | ((int)('8') << 24)),
|
||||
BGR233 = ((int)('B') | ((int)('G') << 8) | ((int)('R') << 16) | ((int)('8') << 24)),
|
||||
|
||||
XRGB4444 = ((int)('X') | ((int)('R') << 8) | ((int)('1') << 16) | ((int)('2') << 24)),
|
||||
XBGR4444 = ((int)('X') | ((int)('B') << 8) | ((int)('1') << 16) | ((int)('2') << 24)),
|
||||
RGBX4444 = ((int)('R') | ((int)('X') << 8) | ((int)('1') << 16) | ((int)('2') << 24)),
|
||||
BGRX4444 = ((int)('B') | ((int)('X') << 8) | ((int)('1') << 16) | ((int)('2') << 24)),
|
||||
|
||||
ARGB4444 = ((int)('A') | ((int)('R') << 8) | ((int)('1') << 16) | ((int)('2') << 24)),
|
||||
ABGR4444 = ((int)('A') | ((int)('B') << 8) | ((int)('1') << 16) | ((int)('2') << 24)),
|
||||
RGBA4444 = ((int)('R') | ((int)('A') << 8) | ((int)('1') << 16) | ((int)('2') << 24)),
|
||||
BGRA4444 = ((int)('B') | ((int)('A') << 8) | ((int)('1') << 16) | ((int)('2') << 24)),
|
||||
|
||||
XRGB1555 = ((int)('X') | ((int)('R') << 8) | ((int)('1') << 16) | ((int)('5') << 24)),
|
||||
XBGR1555 = ((int)('X') | ((int)('B') << 8) | ((int)('1') << 16) | ((int)('5') << 24)),
|
||||
RGBX5551 = ((int)('R') | ((int)('X') << 8) | ((int)('1') << 16) | ((int)('5') << 24)),
|
||||
BGRX5551 = ((int)('B') | ((int)('X') << 8) | ((int)('1') << 16) | ((int)('5') << 24)),
|
||||
|
||||
ARGB1555 = ((int)('A') | ((int)('R') << 8) | ((int)('1') << 16) | ((int)('5') << 24)),
|
||||
ABGR1555 = ((int)('A') | ((int)('B') << 8) | ((int)('1') << 16) | ((int)('5') << 24)),
|
||||
RGBA5551 = ((int)('R') | ((int)('A') << 8) | ((int)('1') << 16) | ((int)('5') << 24)),
|
||||
BGRA5551 = ((int)('B') | ((int)('A') << 8) | ((int)('1') << 16) | ((int)('5') << 24)),
|
||||
|
||||
RGB565 = ((int)('R') | ((int)('G') << 8) | ((int)('1') << 16) | ((int)('6') << 24)),
|
||||
BGR565 = ((int)('B') | ((int)('G') << 8) | ((int)('1') << 16) | ((int)('6') << 24)),
|
||||
|
||||
RGB888 = ((int)('R') | ((int)('G') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
|
||||
BGR888 = ((int)('B') | ((int)('G') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
|
||||
|
||||
XRGB8888 = ((int)('X') | ((int)('R') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
|
||||
XBGR8888 = ((int)('X') | ((int)('B') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
|
||||
RGBX8888 = ((int)('R') | ((int)('X') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
|
||||
BGRX8888 = ((int)('B') | ((int)('X') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
|
||||
|
||||
ARGB8888 = ((int)('A') | ((int)('R') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
|
||||
ABGR8888 = ((int)('A') | ((int)('B') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
|
||||
RGBA8888 = ((int)('R') | ((int)('A') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
|
||||
BGRA8888 = ((int)('B') | ((int)('A') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
|
||||
|
||||
XRGB2101010 = ((int)('X') | ((int)('R') << 8) | ((int)('3') << 16) | ((int)('0') << 24)),
|
||||
XBGR2101010 = ((int)('X') | ((int)('B') << 8) | ((int)('3') << 16) | ((int)('0') << 24)),
|
||||
RGBX1010102 = ((int)('R') | ((int)('X') << 8) | ((int)('3') << 16) | ((int)('0') << 24)),
|
||||
BGRX1010102 = ((int)('B') | ((int)('X') << 8) | ((int)('3') << 16) | ((int)('0') << 24)),
|
||||
|
||||
ARGB2101010 = ((int)('A') | ((int)('R') << 8) | ((int)('3') << 16) | ((int)('0') << 24)),
|
||||
ABGR2101010 = ((int)('A') | ((int)('B') << 8) | ((int)('3') << 16) | ((int)('0') << 24)),
|
||||
RGBA1010102 = ((int)('R') | ((int)('A') << 8) | ((int)('3') << 16) | ((int)('0') << 24)),
|
||||
BGRA1010102 = ((int)('B') | ((int)('A') << 8) | ((int)('3') << 16) | ((int)('0') << 24)),
|
||||
|
||||
YUYV = ((int)('Y') | ((int)('U') << 8) | ((int)('Y') << 16) | ((int)('V') << 24)),
|
||||
YVYU = ((int)('Y') | ((int)('V') << 8) | ((int)('Y') << 16) | ((int)('U') << 24)),
|
||||
UYVY = ((int)('U') | ((int)('Y') << 8) | ((int)('V') << 16) | ((int)('Y') << 24)),
|
||||
VYUY = ((int)('V') | ((int)('Y') << 8) | ((int)('U') << 16) | ((int)('Y') << 24)),
|
||||
|
||||
AYUV = ((int)('A') | ((int)('Y') << 8) | ((int)('U') << 16) | ((int)('V') << 24)),
|
||||
|
||||
NV12 = ((int)('N') | ((int)('V') << 8) | ((int)('1') << 16) | ((int)('2') << 24)),
|
||||
NV21 = ((int)('N') | ((int)('V') << 8) | ((int)('2') << 16) | ((int)('1') << 24)),
|
||||
NV16 = ((int)('N') | ((int)('V') << 8) | ((int)('1') << 16) | ((int)('6') << 24)),
|
||||
NV61 = ((int)('N') | ((int)('V') << 8) | ((int)('6') << 16) | ((int)('1') << 24)),
|
||||
|
||||
YUV410 = ((int)('Y') | ((int)('U') << 8) | ((int)('V') << 16) | ((int)('9') << 24)),
|
||||
YVU410 = ((int)('Y') | ((int)('V') << 8) | ((int)('U') << 16) | ((int)('9') << 24)),
|
||||
YUV411 = ((int)('Y') | ((int)('U') << 8) | ((int)('1') << 16) | ((int)('1') << 24)),
|
||||
YVU411 = ((int)('Y') | ((int)('V') << 8) | ((int)('1') << 16) | ((int)('1') << 24)),
|
||||
YUV420 = ((int)('Y') | ((int)('U') << 8) | ((int)('1') << 16) | ((int)('2') << 24)),
|
||||
YVU420 = ((int)('Y') | ((int)('V') << 8) | ((int)('1') << 16) | ((int)('2') << 24)),
|
||||
YUV422 = ((int)('Y') | ((int)('U') << 8) | ((int)('1') << 16) | ((int)('6') << 24)),
|
||||
YVU422 = ((int)('Y') | ((int)('V') << 8) | ((int)('1') << 16) | ((int)('6') << 24)),
|
||||
YUV444 = ((int)('Y') | ((int)('U') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
|
||||
YVU444 = ((int)('Y') | ((int)('V') << 8) | ((int)('2') << 16) | ((int)('4') << 24)),
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum SurfaceFlags
|
||||
{
|
||||
Scanout = (1 << 0),
|
||||
Cursor64x64 = (1 << 1),
|
||||
Rendering = (1 << 2),
|
||||
Write = (1 << 3),
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct BufferObject : IEquatable<BufferObject>
|
||||
{
|
||||
private IntPtr buffer;
|
||||
|
||||
public static readonly BufferObject Zero =
|
||||
default(BufferObject);
|
||||
|
||||
public int Write(byte[] data)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
fixed (byte* pdata = data)
|
||||
{
|
||||
return Gbm.BOWrite(buffer, (IntPtr)pdata, (IntPtr)data.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetUserData(IntPtr data, DestroyUserDataCallback destroyFB)
|
||||
{
|
||||
Gbm.BOSetUserData(buffer, data, destroyFB);
|
||||
}
|
||||
|
||||
public Device Device
|
||||
{
|
||||
get { return Gbm.BOGetDevice(buffer); }
|
||||
}
|
||||
|
||||
public int Handle
|
||||
{
|
||||
get { return Gbm.BOGetHandle(buffer).ToInt32(); }
|
||||
}
|
||||
|
||||
public int Width
|
||||
{
|
||||
get { return Gbm.BOGetWidth(buffer); }
|
||||
}
|
||||
|
||||
public int Height
|
||||
{
|
||||
get { return Gbm.BOGetHeight(buffer); }
|
||||
}
|
||||
|
||||
public int Stride
|
||||
{
|
||||
get { return Gbm.BOGetStride(buffer); }
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Gbm.DestroyBuffer(this);
|
||||
buffer = IntPtr.Zero;
|
||||
}
|
||||
|
||||
public static bool operator ==(BufferObject left, BufferObject right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
public static bool operator !=(BufferObject left, BufferObject right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return
|
||||
obj is BufferObject &&
|
||||
this.Equals((BufferObject)obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return buffer.GetHashCode();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("[BufferObject: {0}]", buffer);
|
||||
}
|
||||
|
||||
public bool Equals(BufferObject other)
|
||||
{
|
||||
return buffer == other.buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
44
GLWidget/OpenTK/Platform/Linux/Bindings/Kms.cs
Normal file
44
GLWidget/OpenTK/Platform/Linux/Bindings/Kms.cs
Normal file
|
@ -0,0 +1,44 @@
|
|||
//
|
||||
// Kms.cs
|
||||
//
|
||||
// Author:
|
||||
// Stefanos A. <stapostol@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2006-2014
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OpenTK.Platform.Linux
|
||||
{
|
||||
internal class Kms
|
||||
{
|
||||
private const string lib = "libkms";
|
||||
|
||||
[DllImport(lib, EntryPoint = "kms_bo_map", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int MapBuffer(IntPtr bo, out IntPtr @out);
|
||||
|
||||
[DllImport(lib, EntryPoint = "kms_bo_unmap", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int UnmapBuffer(IntPtr bo);
|
||||
}
|
||||
}
|
||||
|
181
GLWidget/OpenTK/Platform/Linux/Bindings/Libc.cs
Normal file
181
GLWidget/OpenTK/Platform/Linux/Bindings/Libc.cs
Normal file
|
@ -0,0 +1,181 @@
|
|||
//
|
||||
// Linux.cs
|
||||
//
|
||||
// Author:
|
||||
// Stefanos A. <stapostol@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2006-2014 Stefanos Apostolopoulos
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
#pragma warning disable 0649 // field is never assigned
|
||||
|
||||
namespace OpenTK.Platform.Linux
|
||||
{
|
||||
internal partial class Libc
|
||||
{
|
||||
private const string lib = "libc";
|
||||
|
||||
[DllImport(lib)]
|
||||
public static extern int dup(int file);
|
||||
|
||||
[DllImport(lib)]
|
||||
public static extern int dup2(int file1, int file2);
|
||||
|
||||
[DllImport(lib)]
|
||||
public static extern int ioctl(int d, JoystickIoctlCode request, ref int data);
|
||||
|
||||
[DllImport(lib)]
|
||||
public static extern int ioctl(int d, JoystickIoctlCode request, StringBuilder data);
|
||||
|
||||
[DllImport(lib)]
|
||||
public static extern int ioctl(int d, uint request, [Out] IntPtr data);
|
||||
|
||||
[DllImport(lib)]
|
||||
public static extern int ioctl(int d, KeyboardIoctlCode request, ref IntPtr data);
|
||||
|
||||
[DllImport(lib)]
|
||||
public static extern int ioctl(int d, KeyboardIoctlCode request, int data);
|
||||
|
||||
[DllImport(lib)]
|
||||
public static extern int open([MarshalAs(UnmanagedType.LPStr)]string pathname, OpenFlags flags);
|
||||
|
||||
[DllImport(lib)]
|
||||
public static extern int open(IntPtr pathname, OpenFlags flags);
|
||||
|
||||
[DllImport(lib)]
|
||||
public static extern int close(int fd);
|
||||
|
||||
[DllImport(lib)]
|
||||
unsafe public static extern IntPtr read(int fd, void* buffer, UIntPtr count);
|
||||
|
||||
public static int read(int fd, out byte b)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
fixed (byte* pb = &b)
|
||||
{
|
||||
return read(fd, pb, (UIntPtr)1).ToInt32();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int read(int fd, out short s)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
fixed (short* ps = &s)
|
||||
{
|
||||
return read(fd, ps, (UIntPtr)2).ToInt32();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport(lib)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool isatty(int fd);
|
||||
}
|
||||
|
||||
internal enum ErrorNumber
|
||||
{
|
||||
Interrupted = 4,
|
||||
Again = 11,
|
||||
InvalidValue = 22,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum DirectionFlags
|
||||
{
|
||||
None = 0,
|
||||
Write = 1,
|
||||
Read = 2
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum OpenFlags
|
||||
{
|
||||
ReadOnly = 0x0000,
|
||||
WriteOnly = 0x0001,
|
||||
ReadWrite = 0x0002,
|
||||
NonBlock = 0x0800,
|
||||
CloseOnExec = 0x0080000
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum JoystickEventType : byte
|
||||
{
|
||||
Button = 0x01, // button pressed/released
|
||||
Axis = 0x02, // joystick moved
|
||||
Init = 0x80 // initial state of device
|
||||
}
|
||||
|
||||
internal enum JoystickIoctlCode : uint
|
||||
{
|
||||
Version = 0x80046a01,
|
||||
Axes = 0x80016a11,
|
||||
Buttons = 0x80016a12,
|
||||
Name128 = (2u << 30) | (0x6A << 8) | (0x13 << 0) | (128 << 16) //JSIOCGNAME(128), which is _IOC(_IO_READ, 'j', 0x13, len)
|
||||
}
|
||||
|
||||
internal enum KeyboardIoctlCode
|
||||
{
|
||||
GetMode = 0x4b44,
|
||||
SetMode = 0x4b45,
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct Stat
|
||||
{
|
||||
public IntPtr dev; /* ID of device containing file */
|
||||
public IntPtr ino; /* inode number */
|
||||
public IntPtr mode; /* protection */
|
||||
public IntPtr nlink; /* number of hard links */
|
||||
public IntPtr uid; /* user ID of owner */
|
||||
public IntPtr gid; /* group ID of owner */
|
||||
public IntPtr rdev; /* device ID (if special file) */
|
||||
public IntPtr size; /* total size, in bytes */
|
||||
public IntPtr blksize; /* blocksize for file system I/O */
|
||||
public IntPtr blocks; /* number of 512B blocks allocated */
|
||||
public IntPtr atime; /* time of last access */
|
||||
public IntPtr mtime; /* time of last modification */
|
||||
public IntPtr ctime; /* time of last status change */
|
||||
}
|
||||
|
||||
internal struct EvdevInputId
|
||||
{
|
||||
public ushort BusType;
|
||||
public ushort Vendor;
|
||||
public ushort Product;
|
||||
public ushort Version;
|
||||
}
|
||||
|
||||
internal struct JoystickEvent
|
||||
{
|
||||
public uint Time; // (u32) event timestamp in milliseconds
|
||||
public short Value; // (s16) value
|
||||
public JoystickEventType Type; // (u8) event type
|
||||
public byte Number; // (u8) axis/button number
|
||||
}
|
||||
}
|
||||
|
63
GLWidget/OpenTK/Platform/Linux/Bindings/Poll.cs
Normal file
63
GLWidget/OpenTK/Platform/Linux/Bindings/Poll.cs
Normal file
|
@ -0,0 +1,63 @@
|
|||
//
|
||||
// Poll.cs
|
||||
//
|
||||
// Author:
|
||||
// Stefanos A. <stapostol@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2006-2014 Stefanos Apostolopoulos
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OpenTK.Platform.Linux
|
||||
{
|
||||
internal partial class Libc
|
||||
{
|
||||
[DllImport("libc", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
|
||||
public static extern int poll(ref PollFD fd, IntPtr fd_count, int timeout);
|
||||
|
||||
public static int poll(ref PollFD fd, int fd_count, int timeout)
|
||||
{
|
||||
return poll(ref fd, (IntPtr)fd_count, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum PollFlags : short
|
||||
{
|
||||
In = 0x01,
|
||||
Pri = 0x02,
|
||||
Out = 0x04,
|
||||
Error = 0x08,
|
||||
Hup = 0x10,
|
||||
Invalid = 0x20,
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct PollFD
|
||||
{
|
||||
public int fd;
|
||||
public PollFlags events;
|
||||
public PollFlags revents;
|
||||
}
|
||||
}
|
||||
|
168
GLWidget/OpenTK/Platform/Linux/Bindings/Terminal.cs
Normal file
168
GLWidget/OpenTK/Platform/Linux/Bindings/Terminal.cs
Normal file
|
@ -0,0 +1,168 @@
|
|||
//
|
||||
// Terminal.cs
|
||||
//
|
||||
// Author:
|
||||
// Stefanos A. <stapostol@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2006-2014 Stefanos Apostolopoulos
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OpenTK.Platform.Linux
|
||||
{
|
||||
internal class Terminal
|
||||
{
|
||||
private const string lib = "libc";
|
||||
|
||||
[DllImport(lib, EntryPoint = "isatty", CallingConvention = CallingConvention.Cdecl)]
|
||||
[return: MarshalAs(UnmanagedType.I4)]
|
||||
public static extern bool IsTerminal(int fd);
|
||||
|
||||
[DllImport(lib, EntryPoint = "tcgetattr", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int GetAttributes(int fd, out TerminalState state);
|
||||
|
||||
[DllImport(lib, EntryPoint = "tcsetattr", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int SetAttributes(int fd, OptionalActions actions, ref TerminalState state);
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum InputFlags
|
||||
{
|
||||
IGNBRK = 1 << 0,
|
||||
BRKINT = 1 << 1,
|
||||
IGNPAR = 1 << 2,
|
||||
PARMRK = 1 << 3,
|
||||
INPCK = 1 << 4,
|
||||
ISTRIP = 1 << 5,
|
||||
INLCR = 1 << 6,
|
||||
IGNCR = 1 << 7,
|
||||
ICRNL = 1 << 8,
|
||||
IUCLC = 1 << 9,
|
||||
IXON = 1 << 10,
|
||||
IXANY = 1 << 11,
|
||||
IXOFF = 1 << 12,
|
||||
IMAXBEL = 1 << 13,
|
||||
IUTF8 = 1 << 14,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum OutputFlags
|
||||
{
|
||||
OPOST = 1 << 1,
|
||||
OLCUC = 1 << 2,
|
||||
ONLCR = 1 << 3,
|
||||
OCRNL = 1 << 4,
|
||||
ONOCR = 1 << 5,
|
||||
ONLRET = 1 << 6,
|
||||
OFILL = 1 << 7,
|
||||
OFDEL = 1 << 8,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum ControlFlags
|
||||
{
|
||||
B0 = 0, // hang up
|
||||
B50,
|
||||
B75,
|
||||
B110,
|
||||
B134,
|
||||
B150,
|
||||
B200,
|
||||
B300,
|
||||
B600,
|
||||
B1200,
|
||||
B1800,
|
||||
B2400,
|
||||
B4800,
|
||||
B9600,
|
||||
B19200,
|
||||
B38400,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum LocalFlags
|
||||
{
|
||||
ISIG = 0x01,
|
||||
ICANON = 0x02,
|
||||
ECHO = 0x08,
|
||||
}
|
||||
|
||||
internal enum OptionalActions
|
||||
{
|
||||
NOW = 0,
|
||||
DRAIN = 1,
|
||||
FLUSH = 2
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct TerminalState
|
||||
{
|
||||
public InputFlags InputMode;
|
||||
public OutputFlags OutputMode;
|
||||
public ControlFlags ControlMode;
|
||||
public LocalFlags LocalMode;
|
||||
public byte LineDiscipline;
|
||||
public ControlCharacters ControlCharacters;
|
||||
public int InputSpeed;
|
||||
public int OutputSpeed;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct ControlCharacters
|
||||
{
|
||||
public byte VINTR;
|
||||
public byte VQUIT;
|
||||
public byte VERASE;
|
||||
public byte VKILL;
|
||||
public byte VEOF;
|
||||
public byte VTIME;
|
||||
public byte VMIN;
|
||||
public byte VSWTC;
|
||||
public byte VSTART;
|
||||
public byte VSTOP;
|
||||
public byte VSUSP;
|
||||
public byte VEOL;
|
||||
public byte VREPRINT;
|
||||
public byte VDISCARD;
|
||||
public byte VWERASE;
|
||||
public byte VLNEXT;
|
||||
public byte VEOL2;
|
||||
public byte C17;
|
||||
public byte C18;
|
||||
public byte C19;
|
||||
public byte C20;
|
||||
public byte C21;
|
||||
public byte C22;
|
||||
public byte C23;
|
||||
public byte C24;
|
||||
public byte C25;
|
||||
public byte C26;
|
||||
public byte C27;
|
||||
public byte C28;
|
||||
public byte C29;
|
||||
public byte C30;
|
||||
public byte C31;
|
||||
|
||||
}
|
||||
}
|
||||
|
44
GLWidget/OpenTK/Platform/Linux/Bindings/Udev.cs
Normal file
44
GLWidget/OpenTK/Platform/Linux/Bindings/Udev.cs
Normal file
|
@ -0,0 +1,44 @@
|
|||
//
|
||||
// Udev.cs
|
||||
//
|
||||
// Author:
|
||||
// Stefanos A. <stapostol@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2006-2014 Stefanos Apostolopoulos
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OpenTK.Platform.Linux
|
||||
{
|
||||
internal class Udev
|
||||
{
|
||||
private const string lib = "libudev";
|
||||
|
||||
[DllImport(lib, EntryPoint = "udev_new", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern IntPtr New();
|
||||
|
||||
[DllImport(lib, EntryPoint = "udev_destroy", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void Destroy(IntPtr Udev);
|
||||
}
|
||||
}
|
||||
|
413
GLWidget/OpenTK/Platform/Linux/LinuxDisplayDriver.cs
Normal file
413
GLWidget/OpenTK/Platform/Linux/LinuxDisplayDriver.cs
Normal file
|
@ -0,0 +1,413 @@
|
|||
//
|
||||
// LinuxDisplayDriver.cs
|
||||
//
|
||||
// Author:
|
||||
// Stefanos A. <stapostol@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2006-2014 Stefanos Apostolopoulos
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
|
||||
namespace OpenTK.Platform.Linux
|
||||
{
|
||||
// Stores platform-specific information about a display
|
||||
internal class LinuxDisplay
|
||||
{
|
||||
public int FD;
|
||||
public IntPtr Connector;
|
||||
public IntPtr Crtc;
|
||||
public IntPtr Encoder;
|
||||
|
||||
unsafe public ModeConnector* pConnector { get { return (ModeConnector*)Connector; } }
|
||||
unsafe public ModeCrtc* pCrtc { get { return (ModeCrtc*)Crtc; } }
|
||||
unsafe public ModeEncoder* pEncoder { get { return (ModeEncoder*)Encoder; } }
|
||||
/*
|
||||
public ModeInfo Mode
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Crtc == IntPtr.Zero)
|
||||
throw new InvalidOperationException();
|
||||
|
||||
unsafe
|
||||
{
|
||||
return pCrtc->mode;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
public ModeInfo OriginalMode;
|
||||
|
||||
public int Id
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Crtc == IntPtr.Zero)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
unsafe
|
||||
{
|
||||
return (int)pCrtc->crtc_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public LinuxDisplay(int fd, IntPtr c, IntPtr e, IntPtr r)
|
||||
{
|
||||
FD = fd;
|
||||
Connector = c;
|
||||
Encoder = e;
|
||||
Crtc = r;
|
||||
unsafe
|
||||
{
|
||||
OriginalMode = pCrtc->mode; // in case we change resolution later on
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class LinuxDisplayDriver : DisplayDeviceBase
|
||||
{
|
||||
private readonly int FD;
|
||||
|
||||
private readonly Dictionary<int, int> DisplayIds =
|
||||
new Dictionary<int, int>();
|
||||
|
||||
public LinuxDisplayDriver(int fd)
|
||||
{
|
||||
Debug.Print("[KMS] Creating LinuxDisplayDriver for fd:{0}", fd);
|
||||
Debug.Indent();
|
||||
try
|
||||
{
|
||||
FD = fd;
|
||||
UpdateDisplays(fd);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Debug.Unindent();
|
||||
}
|
||||
}
|
||||
|
||||
/// \internal
|
||||
/// <summary>
|
||||
/// Queries the specified GPU for connected displays and, optionally,
|
||||
/// returns the list of displays.
|
||||
/// </summary>
|
||||
/// <returns><c>true</c>, if at least one display is connected, <c>false</c> otherwise.</returns>
|
||||
/// <param name="fd">The fd for the GPU to query, obtained through open("/dev/dri/card0").</param>
|
||||
/// <param name="displays">
|
||||
/// If not null, this will contain a list <see cref="LinuxDisplay"/> instances,
|
||||
/// one for each connected display.
|
||||
/// </param>
|
||||
internal static bool QueryDisplays(int fd, List<LinuxDisplay> displays)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
bool has_displays = false;
|
||||
if (displays != null)
|
||||
{
|
||||
displays.Clear();
|
||||
}
|
||||
|
||||
ModeRes* resources = (ModeRes*)Drm.ModeGetResources(fd);
|
||||
if (resources == null)
|
||||
{
|
||||
Debug.Print("[KMS] Drm.ModeGetResources failed.");
|
||||
return false;
|
||||
}
|
||||
Debug.Print("[KMS] DRM found {0} connectors", resources->count_connectors);
|
||||
|
||||
// Search for a valid connector
|
||||
ModeConnector* connector = null;
|
||||
for (int i = 0; i < resources->count_connectors; i++)
|
||||
{
|
||||
connector = (ModeConnector*)Drm.ModeGetConnector(fd,
|
||||
*(resources->connectors + i));
|
||||
if (connector != null)
|
||||
{
|
||||
bool success = false;
|
||||
LinuxDisplay display = null;
|
||||
try
|
||||
{
|
||||
if (connector->connection == ModeConnection.Connected &&
|
||||
connector->count_modes > 0)
|
||||
{
|
||||
success = QueryDisplay(fd, connector, out display);
|
||||
has_displays |= success;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.Print("[KMS] Failed to add display. Error: {0}", e);
|
||||
}
|
||||
|
||||
if (success && displays != null)
|
||||
{
|
||||
displays.Add(display);
|
||||
}
|
||||
else
|
||||
{
|
||||
Drm.ModeFreeConnector((IntPtr)connector);
|
||||
connector = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return has_displays;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateDisplays(int fd)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
AvailableDevices.Clear();
|
||||
DisplayIds.Clear();
|
||||
|
||||
List<LinuxDisplay> displays = new List<LinuxDisplay>();
|
||||
if (QueryDisplays(fd, displays))
|
||||
{
|
||||
foreach (LinuxDisplay display in displays)
|
||||
{
|
||||
AddDisplay(display);
|
||||
}
|
||||
}
|
||||
|
||||
if (AvailableDevices.Count == 0)
|
||||
{
|
||||
Debug.Print("[KMS] Failed to find any active displays");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private unsafe static ModeEncoder* GetEncoder(int fd, ModeConnector* c)
|
||||
{
|
||||
ModeEncoder* encoder = null;
|
||||
for (int i = 0; i < c->count_encoders && encoder == null; i++)
|
||||
{
|
||||
ModeEncoder* e = (ModeEncoder*)Drm.ModeGetEncoder(
|
||||
fd, *(c->encoders + i));
|
||||
if (e != null)
|
||||
{
|
||||
if (e->encoder_id == c->encoder_id)
|
||||
{
|
||||
encoder = e;
|
||||
}
|
||||
else
|
||||
{
|
||||
Drm.ModeFreeEncoder((IntPtr)e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (encoder != null)
|
||||
{
|
||||
Debug.Print("[KMS] Encoder {0} found for connector {1}",
|
||||
encoder->encoder_id, c->connector_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Print("[KMS] Failed to find encoder for connector {0}", c->connector_id);
|
||||
}
|
||||
|
||||
return encoder;
|
||||
}
|
||||
|
||||
private unsafe static ModeCrtc* GetCrtc(int fd, ModeEncoder* encoder)
|
||||
{
|
||||
ModeCrtc* crtc = (ModeCrtc*)Drm.ModeGetCrtc(fd, encoder->crtc_id);
|
||||
if (crtc != null)
|
||||
{
|
||||
Debug.Print("[KMS] CRTC {0} found for encoder {1}",
|
||||
encoder->crtc_id, encoder->encoder_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Print("[KMS] Failed to find crtc {0} for encoder {1}",
|
||||
encoder->crtc_id, encoder->encoder_id);
|
||||
}
|
||||
return crtc;
|
||||
}
|
||||
|
||||
private unsafe static void GetModes(LinuxDisplay display, DisplayResolution[] modes, out DisplayResolution current)
|
||||
{
|
||||
int mode_count = display.pConnector->count_modes;
|
||||
Debug.Print("[KMS] Display supports {0} mode(s)", mode_count);
|
||||
for (int i = 0; i < mode_count; i++)
|
||||
{
|
||||
ModeInfo* mode = display.pConnector->modes + i;
|
||||
if (mode != null)
|
||||
{
|
||||
Debug.Print("Mode {0}: {1}x{2} @{3}", i,
|
||||
mode->hdisplay, mode->vdisplay, mode->vrefresh);
|
||||
DisplayResolution res = GetDisplayResolution(mode);
|
||||
modes[i] = res;
|
||||
}
|
||||
}
|
||||
|
||||
if (display.pCrtc->mode_valid != 0)
|
||||
{
|
||||
ModeInfo cmode = display.pCrtc->mode;
|
||||
current = GetDisplayResolution(&cmode);
|
||||
}
|
||||
else
|
||||
{
|
||||
current = GetDisplayResolution(display.pConnector->modes);
|
||||
}
|
||||
Debug.Print("Current mode: {0}", current.ToString());
|
||||
}
|
||||
|
||||
private Rectangle GetBounds(DisplayResolution current)
|
||||
{
|
||||
// Note: since we are not running a display manager, we are free
|
||||
// to choose the display layout for multiple displays ourselves.
|
||||
// We choose the simplest layout: displays are laid out side-by-side
|
||||
// from left to right. Primary display is the first display we encounter.
|
||||
int x = AvailableDevices.Count == 0 ?
|
||||
0 : AvailableDevices[AvailableDevices.Count - 1].Bounds.Right;
|
||||
int y = 0;
|
||||
|
||||
return new Rectangle(
|
||||
x, y, current.Width, current.Height);
|
||||
}
|
||||
|
||||
private void UpdateDisplayIndices(LinuxDisplay display, DisplayDevice device)
|
||||
{
|
||||
if (!DisplayIds.ContainsKey(display.Id))
|
||||
{
|
||||
Debug.Print("[KMS] Adding display {0} as {1}", display.Id, AvailableDevices.Count);
|
||||
DisplayIds.Add(display.Id, AvailableDevices.Count);
|
||||
}
|
||||
int index = DisplayIds[display.Id];
|
||||
if (index >= AvailableDevices.Count)
|
||||
{
|
||||
AvailableDevices.Add(device);
|
||||
}
|
||||
else
|
||||
{
|
||||
AvailableDevices[index] = device;
|
||||
}
|
||||
}
|
||||
|
||||
private unsafe static bool QueryDisplay(int fd, ModeConnector* c, out LinuxDisplay display)
|
||||
{
|
||||
display = null;
|
||||
|
||||
// Find corresponding encoder
|
||||
ModeEncoder* encoder = GetEncoder(fd, c);
|
||||
if (encoder == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ModeCrtc* crtc = GetCrtc(fd, encoder);
|
||||
if (crtc == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
display = new LinuxDisplay(fd, (IntPtr)c, (IntPtr)encoder, (IntPtr)crtc);
|
||||
return true;
|
||||
}
|
||||
|
||||
private unsafe void AddDisplay(LinuxDisplay display)
|
||||
{
|
||||
DisplayResolution[] modes = new DisplayResolution[display.pConnector->count_modes];
|
||||
DisplayResolution current;
|
||||
GetModes(display, modes, out current);
|
||||
|
||||
bool is_primary = AvailableDevices.Count == 0;
|
||||
DisplayDevice device = new DisplayDevice(current, is_primary,
|
||||
modes, GetBounds(current), display);
|
||||
|
||||
if (is_primary)
|
||||
{
|
||||
Primary = device;
|
||||
}
|
||||
|
||||
UpdateDisplayIndices(display, device);
|
||||
|
||||
Debug.Print("[KMS] Added DisplayDevice {0}", device);
|
||||
}
|
||||
|
||||
private unsafe static DisplayResolution GetDisplayResolution(ModeInfo* mode)
|
||||
{
|
||||
return new DisplayResolution(
|
||||
0, 0,
|
||||
mode->hdisplay, mode->vdisplay,
|
||||
32, // This is actually part of the framebuffer, not the DisplayResolution
|
||||
mode->vrefresh);
|
||||
}
|
||||
|
||||
private unsafe static ModeInfo* GetModeInfo(LinuxDisplay display, DisplayResolution resolution)
|
||||
{
|
||||
for (int i = 0; i < display.pConnector->count_modes; i++)
|
||||
{
|
||||
ModeInfo* mode = display.pConnector->modes + i;
|
||||
if (mode != null &&
|
||||
mode->hdisplay == resolution.Width &&
|
||||
mode->vdisplay == resolution.Height)
|
||||
{
|
||||
return mode;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public override bool TryChangeResolution(DisplayDevice device, DisplayResolution resolution)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
LinuxDisplay display = (LinuxDisplay)device.Id;
|
||||
ModeInfo* mode = GetModeInfo(display, resolution);
|
||||
int connector_id = display.pConnector->connector_id;
|
||||
if (mode != null)
|
||||
{
|
||||
return Drm.ModeSetCrtc(FD, display.Id, 0, 0, 0,
|
||||
&connector_id, 1, mode) == 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool TryRestoreResolution(DisplayDevice device)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
LinuxDisplay display = (LinuxDisplay)device.Id;
|
||||
ModeInfo mode = display.OriginalMode;
|
||||
int connector_id = display.pConnector->connector_id;
|
||||
return Drm.ModeSetCrtc(FD, display.Id, 0, 0, 0,
|
||||
&connector_id, 1, &mode) == 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
197
GLWidget/OpenTK/Platform/Linux/LinuxFactory.cs
Normal file
197
GLWidget/OpenTK/Platform/Linux/LinuxFactory.cs
Normal file
|
@ -0,0 +1,197 @@
|
|||
//
|
||||
// LinuxFactory.cs
|
||||
//
|
||||
// Author:
|
||||
// Stefanos A. <stapostol@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2006-2014 Stefanos Apostolopoulos
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using OpenTK.Graphics;
|
||||
using OpenTK.Platform.Egl;
|
||||
|
||||
namespace OpenTK.Platform.Linux
|
||||
{
|
||||
using Egl = OpenTK.Platform.Egl.Egl;
|
||||
|
||||
// Linux KMS platform
|
||||
internal class LinuxFactory : PlatformFactoryBase
|
||||
{
|
||||
private int _fd;
|
||||
private IntPtr gbm_device;
|
||||
private IntPtr egl_display;
|
||||
|
||||
private const string gpu_path = "/dev/dri"; // card0, card1, ...
|
||||
|
||||
public LinuxFactory()
|
||||
{
|
||||
Debug.Print("[KMS] Using Linux/KMS backend.");
|
||||
}
|
||||
|
||||
private int gpu_fd
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (_fd == 0)
|
||||
{
|
||||
_fd = CreateDisplay(out gbm_device, out egl_display);
|
||||
}
|
||||
return _fd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static int CreateDisplay(out IntPtr gbm_device, out IntPtr egl_display)
|
||||
{
|
||||
// Query all GPUs until we find one that has a connected display.
|
||||
// This is necessary in multi-gpu systems, where only one GPU
|
||||
// can output a signal.
|
||||
// Todo: allow OpenTK to drive multiple GPUs
|
||||
// Todo: allow OpenTK to run on an offscreen GPU
|
||||
// Todo: allow the user to pick a GPU
|
||||
int fd = 0;
|
||||
gbm_device = IntPtr.Zero;
|
||||
egl_display = IntPtr.Zero;
|
||||
|
||||
var files = Directory.GetFiles(gpu_path);
|
||||
foreach (var gpu in files)
|
||||
{
|
||||
if (Path.GetFileName(gpu).StartsWith("card"))
|
||||
{
|
||||
int test_fd = SetupDisplay(gpu, out gbm_device, out egl_display);
|
||||
if (test_fd >= 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (LinuxDisplayDriver.QueryDisplays(test_fd, null))
|
||||
{
|
||||
fd = test_fd;
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.WriteLine(e.ToString());
|
||||
}
|
||||
|
||||
Debug.Print("[KMS] GPU '{0}' is not connected, skipping.", gpu);
|
||||
Libc.close(test_fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fd == 0)
|
||||
{
|
||||
Debug.Print("[Error] No valid GPU found, bailing out.");
|
||||
throw new PlatformNotSupportedException();
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
private static int SetupDisplay(string gpu, out IntPtr gbm_device, out IntPtr egl_display)
|
||||
{
|
||||
Debug.Print("[KMS] Attempting to use gpu '{0}'.", gpu);
|
||||
|
||||
gbm_device = IntPtr.Zero;
|
||||
egl_display = IntPtr.Zero;
|
||||
|
||||
int fd = Libc.open(gpu, OpenFlags.ReadWrite | OpenFlags.CloseOnExec);
|
||||
if (fd < 0)
|
||||
{
|
||||
Debug.Print("[KMS] Failed to open gpu");
|
||||
return fd;
|
||||
}
|
||||
Debug.Print("[KMS] GPU '{0}' opened as fd:{1}", gpu, fd);
|
||||
|
||||
gbm_device = Gbm.CreateDevice(fd);
|
||||
if (gbm_device == IntPtr.Zero)
|
||||
{
|
||||
throw new NotSupportedException("[KMS] Failed to create GBM device");
|
||||
}
|
||||
Debug.Print("[KMS] GBM {0:x} created successfully; ", gbm_device);
|
||||
|
||||
egl_display = Egl.GetDisplay(gbm_device);
|
||||
if (egl_display == IntPtr.Zero)
|
||||
{
|
||||
throw new NotSupportedException("[KMS] Failed to create EGL display");
|
||||
}
|
||||
Debug.Print("[KMS] EGL display {0:x} created successfully", egl_display);
|
||||
|
||||
int major, minor;
|
||||
if (!Egl.Initialize(egl_display, out major, out minor))
|
||||
{
|
||||
ErrorCode error = Egl.GetError();
|
||||
throw new NotSupportedException("[KMS] Failed to initialize EGL display. Error code: " + error);
|
||||
}
|
||||
Debug.Print("[KMS] EGL {0}.{1} initialized successfully on display {2:x}", major, minor, egl_display);
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool manual)
|
||||
{
|
||||
if (egl_display != IntPtr.Zero)
|
||||
{
|
||||
Debug.Print("[KMS] Terminating EGL.");
|
||||
Egl.Terminate(egl_display);
|
||||
egl_display = IntPtr.Zero;
|
||||
}
|
||||
if (gbm_device != IntPtr.Zero)
|
||||
{
|
||||
Debug.Print("[KMS] Destroying GBM device.");
|
||||
Gbm.DestroyDevice(gbm_device);
|
||||
gbm_device = IntPtr.Zero;
|
||||
}
|
||||
if (_fd >= 0)
|
||||
{
|
||||
Debug.Print("[KMS] Closing GPU fd.");
|
||||
Libc.close(_fd);
|
||||
}
|
||||
|
||||
base.Dispose(manual);
|
||||
}
|
||||
|
||||
public override IDisplayDeviceDriver CreateDisplayDeviceDriver()
|
||||
{
|
||||
return new LinuxDisplayDriver(gpu_fd);
|
||||
}
|
||||
|
||||
public override IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
|
||||
{
|
||||
return new LinuxGraphicsContext(mode, (LinuxWindowInfo)window, shareContext, major, minor, flags);
|
||||
}
|
||||
|
||||
public override GraphicsContext.GetCurrentContextDelegate CreateGetCurrentGraphicsContext()
|
||||
{
|
||||
return (GraphicsContext.GetCurrentContextDelegate)delegate
|
||||
{
|
||||
return new ContextHandle(Egl.GetCurrentContext());
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
318
GLWidget/OpenTK/Platform/Linux/LinuxGraphicsContext.cs
Normal file
318
GLWidget/OpenTK/Platform/Linux/LinuxGraphicsContext.cs
Normal file
|
@ -0,0 +1,318 @@
|
|||
//
|
||||
// LinuxGraphicsContext.cs
|
||||
//
|
||||
// Author:
|
||||
// thefiddler <stapostol@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2006-2014
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace OpenTK.Platform.Linux
|
||||
{
|
||||
/// \internal
|
||||
/// <summary>
|
||||
/// Defines an IGraphicsContext implementation for the Linux KMS framebuffer.
|
||||
/// For Linux/X11 and other Unix operating systems, use the more generic
|
||||
/// <see cref="OpenTK.Platform.Egl.EglUnixContext"/> instead.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note: to display our results, we need to allocate a GBM framebuffer
|
||||
/// and point the scanout address to that via Drm.ModeSetCrtc.
|
||||
/// </remarks>
|
||||
internal class LinuxGraphicsContext : Egl.EglUnixContext
|
||||
{
|
||||
private BufferObject bo, bo_next;
|
||||
private int fd;
|
||||
private bool is_flip_queued;
|
||||
private int swap_interval;
|
||||
|
||||
public LinuxGraphicsContext(GraphicsMode mode, LinuxWindowInfo window, IGraphicsContext sharedContext,
|
||||
int major, int minor, GraphicsContextFlags flags)
|
||||
: base(mode, window, sharedContext, major, minor, flags)
|
||||
{
|
||||
if (mode.Buffers < 1)
|
||||
{
|
||||
throw new ArgumentException();
|
||||
}
|
||||
fd = window.FD;
|
||||
|
||||
PageFlip = HandlePageFlip;
|
||||
PageFlipPtr = Marshal.GetFunctionPointerForDelegate(PageFlip);
|
||||
}
|
||||
|
||||
public override void SwapBuffers()
|
||||
{
|
||||
base.SwapBuffers();
|
||||
|
||||
if (is_flip_queued)
|
||||
{
|
||||
// Todo: if we don't wait for the page flip,
|
||||
// we drop all rendering buffers and get a crash
|
||||
// in Egl.SwapBuffers(). We need to fix that
|
||||
// before we can disable vsync.
|
||||
WaitFlip(true); // WaitFlip(SwapInterval > 0)
|
||||
if (is_flip_queued)
|
||||
{
|
||||
Debug.Print("[KMS] Dropping frame");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bo_next = LockSurface();
|
||||
int fb = GetFramebuffer(bo_next);
|
||||
QueueFlip(fb);
|
||||
}
|
||||
|
||||
public override void Update(IWindowInfo window)
|
||||
{
|
||||
WaitFlip(true);
|
||||
|
||||
base.SwapBuffers();
|
||||
|
||||
bo = LockSurface();
|
||||
int fb = GetFramebuffer(bo);
|
||||
SetScanoutRegion(fb);
|
||||
}
|
||||
|
||||
public override int SwapInterval
|
||||
{
|
||||
get
|
||||
{
|
||||
return swap_interval;
|
||||
}
|
||||
set
|
||||
{
|
||||
// We only support a SwapInterval of 0 (immediate)
|
||||
// or 1 (vsynced).
|
||||
// Todo: add support for SwapInterval of -1 (adaptive).
|
||||
// This requires a small change in WaitFlip().
|
||||
swap_interval = Math.Clamp(value, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
private void WaitFlip(bool block)
|
||||
{
|
||||
PollFD fds = new PollFD();
|
||||
fds.fd = fd;
|
||||
fds.events = PollFlags.In;
|
||||
|
||||
EventContext evctx = new EventContext();
|
||||
evctx.version = EventContext.Version;
|
||||
evctx.page_flip_handler = PageFlipPtr;
|
||||
|
||||
int timeout = block ? -1 : 0;
|
||||
|
||||
while (is_flip_queued)
|
||||
{
|
||||
fds.revents = 0;
|
||||
if (Libc.poll(ref fds, 1, timeout) < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if ((fds.revents & (PollFlags.Hup | PollFlags.Error)) != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if ((fds.revents & PollFlags.In) != 0)
|
||||
{
|
||||
Drm.HandleEvent(fd, ref evctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Page flip has taken place, update buffer objects
|
||||
if (!is_flip_queued)
|
||||
{
|
||||
IntPtr gbm_surface = WindowInfo.Handle;
|
||||
Gbm.ReleaseBuffer(gbm_surface, bo);
|
||||
bo = bo_next;
|
||||
}
|
||||
}
|
||||
|
||||
private void QueueFlip(int buffer)
|
||||
{
|
||||
LinuxWindowInfo wnd = WindowInfo as LinuxWindowInfo;
|
||||
if (wnd == null)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
unsafe
|
||||
{
|
||||
int ret = Drm.ModePageFlip(fd, wnd.DisplayDevice.Id, buffer,
|
||||
PageFlipFlags.FlipEvent, IntPtr.Zero);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
Debug.Print("[KMS] Failed to enqueue framebuffer flip. Error: {0}", ret);
|
||||
}
|
||||
|
||||
is_flip_queued = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetScanoutRegion(int buffer)
|
||||
{
|
||||
LinuxWindowInfo wnd = WindowInfo as LinuxWindowInfo;
|
||||
if (wnd == null)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
unsafe
|
||||
{
|
||||
ModeInfo* mode = wnd.DisplayDevice.pConnector->modes;
|
||||
int connector_id = wnd.DisplayDevice.pConnector->connector_id;
|
||||
int crtc_id = wnd.DisplayDevice.Id;
|
||||
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int connector_count = 1;
|
||||
int ret = Drm.ModeSetCrtc(fd, crtc_id, buffer, x, y,
|
||||
&connector_id, connector_count, mode);
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
Debug.Print("[KMS] Drm.ModeSetCrtc{0}, {1}, {2}, {3}, {4:x}, {5}, {6:x}) failed. Error: {7}",
|
||||
fd, crtc_id, buffer, x, y, (IntPtr)connector_id, connector_count, (IntPtr)mode, ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private BufferObject LockSurface()
|
||||
{
|
||||
IntPtr gbm_surface = WindowInfo.Handle;
|
||||
return Gbm.LockFrontBuffer(gbm_surface);
|
||||
}
|
||||
|
||||
private int GetFramebuffer(BufferObject bo)
|
||||
{
|
||||
if (bo == BufferObject.Zero)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
int bo_handle = bo.Handle;
|
||||
if (bo_handle == 0)
|
||||
{
|
||||
Debug.Print("[KMS] Gbm.BOGetHandle({0:x}) failed.", bo);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
int width = bo.Width;
|
||||
int height = bo.Height;
|
||||
int bpp = Mode.ColorFormat.BitsPerPixel;
|
||||
int depth = Mode.Depth;
|
||||
int stride = bo.Stride;
|
||||
|
||||
if (width == 0 || height == 0 || bpp == 0)
|
||||
{
|
||||
Debug.Print("[KMS] Invalid framebuffer format: {0}x{1} {2} {3} {4}",
|
||||
width, height, stride, bpp, depth);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
int buffer;
|
||||
int ret = Drm.ModeAddFB(
|
||||
fd, width, height,
|
||||
(byte)depth, (byte)bpp, stride, bo_handle,
|
||||
out buffer);
|
||||
if (ret != 0)
|
||||
{
|
||||
Debug.Print("[KMS] Drm.ModeAddFB({0}, {1}, {2}, {3}, {4}, {5}, {6}) failed. Error: {7}",
|
||||
fd, width, height, depth, bpp, stride, bo_handle, ret);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
bo.SetUserData((IntPtr)buffer, DestroyFB);
|
||||
return buffer;
|
||||
|
||||
fail:
|
||||
Debug.Print("[Error] Failed to create framebuffer.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
private readonly IntPtr PageFlipPtr;
|
||||
private readonly PageFlipCallback PageFlip;
|
||||
|
||||
private void HandlePageFlip(int fd,
|
||||
int sequence,
|
||||
int tv_sec,
|
||||
int tv_usec,
|
||||
IntPtr user_data)
|
||||
{
|
||||
is_flip_queued = false;
|
||||
}
|
||||
|
||||
private static readonly DestroyUserDataCallback DestroyFB = HandleDestroyFB;
|
||||
|
||||
private static void HandleDestroyFB(BufferObject bo, IntPtr data)
|
||||
{
|
||||
IntPtr gbm = bo.Device;
|
||||
int fb = data.ToInt32();
|
||||
Debug.Print("[KMS] Destroying framebuffer {0}", fb);
|
||||
|
||||
if (fb != 0)
|
||||
{
|
||||
Drm.ModeRmFB(Gbm.DeviceGetFD(gbm), fb);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Dispose(bool manual)
|
||||
{
|
||||
if (manual)
|
||||
{
|
||||
// Reset the scanout region
|
||||
LinuxWindowInfo wnd = WindowInfo as LinuxWindowInfo;
|
||||
if (wnd != null)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
int connector_id = wnd.DisplayDevice.pConnector->connector_id;
|
||||
ModeInfo mode = wnd.DisplayDevice.OriginalMode;
|
||||
Drm.ModeSetCrtc(fd,
|
||||
wnd.DisplayDevice.pCrtc->crtc_id,
|
||||
wnd.DisplayDevice.pCrtc->buffer_id,
|
||||
wnd.DisplayDevice.pCrtc->x,
|
||||
wnd.DisplayDevice.pCrtc->y,
|
||||
&connector_id,
|
||||
1,
|
||||
&mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
base.Dispose(manual);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
55
GLWidget/OpenTK/Platform/Linux/LinuxWindowInfo.cs
Normal file
55
GLWidget/OpenTK/Platform/Linux/LinuxWindowInfo.cs
Normal file
|
@ -0,0 +1,55 @@
|
|||
//
|
||||
// LinuxWindowInfo.cs
|
||||
//
|
||||
// Author:
|
||||
// Stefanos A. <stapostol@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2006-2014 Stefanos Apostolopoulos
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using OpenTK.Platform.Egl;
|
||||
|
||||
namespace OpenTK.Platform.Linux
|
||||
{
|
||||
internal class LinuxWindowInfo : EglWindowInfo
|
||||
{
|
||||
public int FD { get; private set; }
|
||||
public LinuxDisplay DisplayDevice { get; private set; }
|
||||
public IntPtr BufferManager { get; private set; }
|
||||
|
||||
public LinuxWindowInfo(IntPtr display, int fd, IntPtr gbm, LinuxDisplay display_device)
|
||||
: base(IntPtr.Zero, display, IntPtr.Zero)
|
||||
{
|
||||
if (display_device == null)
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
FD = fd;
|
||||
BufferManager = gbm;
|
||||
DisplayDevice = display_device;
|
||||
// The window handle and surface handle must
|
||||
// be filled in manually once they are known.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
141
GLWidget/OpenTK/Platform/MacOS/Carbon/Cgl.cs
Normal file
141
GLWidget/OpenTK/Platform/MacOS/Carbon/Cgl.cs
Normal file
|
@ -0,0 +1,141 @@
|
|||
//
|
||||
// Cgl.cs
|
||||
//
|
||||
// Author:
|
||||
// Stefanos A. <stapostol@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2006-2014 Stefanos Apostolopoulos
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OpenTK.Platform.MacOS
|
||||
{
|
||||
using CGLPixelFormat = IntPtr;
|
||||
using CGLContext = IntPtr;
|
||||
|
||||
internal static class Cgl
|
||||
{
|
||||
internal enum PixelFormatBool
|
||||
{
|
||||
None = 0,
|
||||
AllRenderers = 1,
|
||||
Doublebuffer = 5,
|
||||
Stereo = 6,
|
||||
AuxBuffers = 7,
|
||||
MinimumPolicy = 51,
|
||||
MaximumPolicy = 52,
|
||||
Offscreen = 53,
|
||||
AuxDepthStencil = 57,
|
||||
ColorFloat = 58,
|
||||
Multisample = 59,
|
||||
Supersample = 60,
|
||||
SampleALpha = 61,
|
||||
SingleRenderer = 71,
|
||||
NoRecovery = 72,
|
||||
Accelerated = 73,
|
||||
ClosestPolicy = 74,
|
||||
BackingStore = 76,
|
||||
Window = 80,
|
||||
Compliant = 83,
|
||||
PBuffer = 90,
|
||||
RemotePBuffer = 91,
|
||||
}
|
||||
|
||||
internal enum PixelFormatInt
|
||||
{
|
||||
ColorSize = 8,
|
||||
AlphaSize = 11,
|
||||
DepthSize = 12,
|
||||
StencilSize = 13,
|
||||
AccumSize = 14,
|
||||
SampleBuffers = 55,
|
||||
Samples = 56,
|
||||
RendererID = 70,
|
||||
DisplayMask = 84,
|
||||
OpenGLProfile = 99,
|
||||
VScreenCount = 128,
|
||||
}
|
||||
|
||||
internal enum OpenGLProfileVersion
|
||||
{
|
||||
Legacy = 0x100,
|
||||
Core3_2 = 0x3200,
|
||||
}
|
||||
|
||||
internal enum ParameterNames
|
||||
{
|
||||
SwapInterval = 222,
|
||||
}
|
||||
|
||||
internal enum Error
|
||||
{
|
||||
None = 0x000,
|
||||
}
|
||||
|
||||
private const string cgl = "/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL";
|
||||
private const string cgs = "/System/Library/Frameworks/Carbon.framework/Versions/Current/Carbon";
|
||||
|
||||
[DllImport(cgl, EntryPoint = "CGLGetError")]
|
||||
internal static extern Error GetError();
|
||||
[DllImport(cgl, EntryPoint = "CGLErrorString")]
|
||||
private static extern IntPtr CGLErrorString(Error code);
|
||||
internal static string ErrorString(Error code)
|
||||
{
|
||||
return Marshal.PtrToStringAnsi(CGLErrorString(code));
|
||||
}
|
||||
|
||||
[DllImport(cgl, EntryPoint = "CGLChoosePixelFormat")]
|
||||
internal static extern Error ChoosePixelFormat(int []attribs, ref CGLPixelFormat format, ref int numPixelFormats);
|
||||
[DllImport(cgl, EntryPoint = "CGLDescribePixelFormat")]
|
||||
internal static extern Error DescribePixelFormat(CGLPixelFormat pix, int pix_num, PixelFormatInt attrib, out int value);
|
||||
[DllImport(cgl, EntryPoint = "CGLDescribePixelFormat")]
|
||||
internal static extern Error DescribePixelFormat(CGLPixelFormat pix, int pix_num, PixelFormatBool attrib, out bool value);
|
||||
[DllImport(cgl, EntryPoint = "CGLGetPixelFormat")]
|
||||
internal static extern CGLPixelFormat GetPixelFormat(CGLContext context);
|
||||
[DllImport(cgl, EntryPoint = "CGLCreateContext")]
|
||||
internal static extern Error CreateContext(CGLPixelFormat format, CGLContext share, ref CGLContext context);
|
||||
[DllImport(cgl, EntryPoint = "CGLDestroyPixelFormat")]
|
||||
internal static extern Error DestroyPixelFormat(CGLPixelFormat format);
|
||||
[DllImport(cgl, EntryPoint = "CGLGetCurrentContext")]
|
||||
internal static extern CGLContext GetCurrentContext();
|
||||
[DllImport(cgl, EntryPoint = "CGLSetCurrentContext")]
|
||||
internal static extern Error SetCurrentContext(CGLContext context);
|
||||
[DllImport(cgl, EntryPoint = "CGLDestroyContext")]
|
||||
internal static extern Error DestroyContext(CGLContext context);
|
||||
[DllImport(cgl, EntryPoint = "CGLSetParameter")]
|
||||
internal static extern Error SetParameter(CGLContext context, int parameter, ref int value);
|
||||
[DllImport(cgl, EntryPoint = "CGLFlushDrawable")]
|
||||
internal static extern Error FlushDrawable(CGLContext context);
|
||||
|
||||
[DllImport(cgl, EntryPoint = "CGLSetSurface")]
|
||||
internal static extern Error SetSurface(CGLContext context, int conId, int winId, int surfId);
|
||||
[DllImport(cgl, EntryPoint = "CGLUpdateContext")]
|
||||
internal static extern Error UpdateContext(CGLContext context);
|
||||
|
||||
[DllImport(cgs, EntryPoint = "CGSMainConnectionID")]
|
||||
internal static extern int MainConnectionID();
|
||||
[DllImport(cgs, EntryPoint = "CGSGetSurfaceCount")]
|
||||
internal static extern Error GetSurfaceCount(int conId, int winId, ref int count);
|
||||
[DllImport(cgs, EntryPoint = "CGSGetSurfaceList")]
|
||||
internal static extern Error GetSurfaceList(int conId, int winId, int count, ref int ids, ref int filled);
|
||||
}
|
||||
}
|
158
GLWidget/OpenTK/Platform/MacOS/Carbon/MacOSKeys.cs
Normal file
158
GLWidget/OpenTK/Platform/MacOS/Carbon/MacOSKeys.cs
Normal file
|
@ -0,0 +1,158 @@
|
|||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2010 the Open Toolkit library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
|
||||
namespace OpenTK.Platform.MacOS
|
||||
{
|
||||
//
|
||||
// http://web.archive.org/web/20100501161453/http://www.classicteck.com/rbarticles/mackeyboard.php
|
||||
|
||||
internal enum MacOSKeyCode
|
||||
{
|
||||
A = 0,
|
||||
B = 11,
|
||||
C = 8,
|
||||
D = 2,
|
||||
E = 14,
|
||||
F = 3,
|
||||
G = 5,
|
||||
H = 4,
|
||||
I = 34,
|
||||
J = 38,
|
||||
K = 40,
|
||||
L = 37,
|
||||
M = 46,
|
||||
N = 45,
|
||||
O = 31,
|
||||
P = 35,
|
||||
Q = 12,
|
||||
R = 15,
|
||||
S = 1,
|
||||
T = 17,
|
||||
U = 32,
|
||||
V = 9,
|
||||
W = 13,
|
||||
X = 7,
|
||||
Y = 16,
|
||||
Z = 6,
|
||||
|
||||
Key_1 = 18,
|
||||
Key_2 = 19,
|
||||
Key_3 = 20,
|
||||
Key_4 = 21,
|
||||
Key_5 = 23,
|
||||
Key_6 = 22,
|
||||
Key_7 = 26,
|
||||
Key_8 = 28,
|
||||
Key_9 = 25,
|
||||
Key_0 = 29,
|
||||
|
||||
Space = 49,
|
||||
Tilde = 50,
|
||||
|
||||
Minus = 27,
|
||||
Equals = 24,
|
||||
BracketLeft = 33,
|
||||
BracketRight = 30,
|
||||
Backslash = 42,
|
||||
Semicolon = 41,
|
||||
Quote = 39,
|
||||
Comma = 43,
|
||||
Period = 47,
|
||||
Slash = 44,
|
||||
|
||||
Enter = 36,
|
||||
Tab = 48,
|
||||
Backspace = 51,
|
||||
Return = 52,
|
||||
Esc = 53,
|
||||
|
||||
Command = 55,
|
||||
Shift = 56,
|
||||
CapsLock = 57,
|
||||
OptionAlt = 58,
|
||||
Control = 59,
|
||||
|
||||
KeyPad_Decimal = 65,
|
||||
KeyPad_Multiply = 67,
|
||||
KeyPad_Add = 69,
|
||||
KeyPad_Divide = 75,
|
||||
KeyPad_Enter = 76,
|
||||
KeyPad_Subtract = 78,
|
||||
KeyPad_Equal = 81,
|
||||
KeyPad_0 = 82,
|
||||
KeyPad_1 = 83,
|
||||
KeyPad_2 = 84,
|
||||
KeyPad_3 = 85,
|
||||
KeyPad_4 = 86,
|
||||
KeyPad_5 = 87,
|
||||
KeyPad_6 = 88,
|
||||
KeyPad_7 = 89,
|
||||
KeyPad_8 = 91,
|
||||
KeyPad_9 = 92,
|
||||
|
||||
F1 = 122,
|
||||
F2 = 120,
|
||||
F3 = 99,
|
||||
F4 = 118,
|
||||
F5 = 96,
|
||||
F6 = 97,
|
||||
F7 = 98,
|
||||
F8 = 100,
|
||||
F9 = 101,
|
||||
F10 = 109,
|
||||
F11 = 103,
|
||||
F12 = 111,
|
||||
F13 = 105,
|
||||
F14 = 107,
|
||||
F15 = 113,
|
||||
|
||||
Menu = 110,
|
||||
|
||||
Insert = 114,
|
||||
Home = 115,
|
||||
Pageup = 116,
|
||||
Del = 117,
|
||||
End = 119,
|
||||
Pagedown = 121,
|
||||
Up = 126,
|
||||
Down = 125,
|
||||
Left = 123,
|
||||
Right = 124,
|
||||
|
||||
|
||||
}
|
||||
[Flags]
|
||||
internal enum MacOSKeyModifiers
|
||||
{
|
||||
None = 0,
|
||||
Shift = 0x0200,
|
||||
CapsLock = 0x0400,
|
||||
Control = 0x1000, //
|
||||
Command = 0x0100, // Open-Apple - Windows key
|
||||
Option = 0x0800, // Option key is same position as the alt key on non-mac keyboards.
|
||||
}
|
||||
}
|
119
GLWidget/OpenTK/Platform/MacOS/CarbonWindowInfo.cs
Normal file
119
GLWidget/OpenTK/Platform/MacOS/CarbonWindowInfo.cs
Normal file
|
@ -0,0 +1,119 @@
|
|||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2009 the Open Toolkit library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
|
||||
namespace OpenTK.Platform.MacOS
|
||||
{
|
||||
/// \internal
|
||||
/// <summary>
|
||||
/// Describes a Carbon window.
|
||||
/// </summary>
|
||||
internal sealed class CarbonWindowInfo : IWindowInfo
|
||||
{
|
||||
private bool ownHandle = false;
|
||||
private bool disposed = false;
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new instance with the specified parameters.
|
||||
/// </summary>
|
||||
/// <param name="windowRef">A valid Carbon window reference.</param>
|
||||
/// <param name="ownHandle"></param>
|
||||
/// <param name="isControl"></param>
|
||||
public CarbonWindowInfo(IntPtr windowRef, bool ownHandle, bool isControl)
|
||||
{
|
||||
this.Handle = windowRef;
|
||||
this.ownHandle = ownHandle;
|
||||
this.IsControl = isControl;
|
||||
}
|
||||
|
||||
public CarbonWindowInfo(IntPtr windowRef, bool ownHandle, bool isControl, GetInt getX, GetInt getY) : this(windowRef, ownHandle, isControl)
|
||||
{
|
||||
this.XOffset = getX;
|
||||
this.YOffset = getY;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the window reference for this instance.
|
||||
/// </summary>
|
||||
public IntPtr Handle { get; set; }
|
||||
|
||||
internal bool GoFullScreenHack { get; set; } = false;
|
||||
|
||||
internal bool GoWindowedHack { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance refers to a System.Windows.Forms.Control.
|
||||
/// </summary>
|
||||
public bool IsControl { get; } = true;
|
||||
|
||||
/// <summary>Returns a System.String that represents the current window.</summary>
|
||||
/// <returns>A System.String that represents the current window.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("MacOS.CarbonWindowInfo: Handle {0}", this.Handle);
|
||||
}
|
||||
|
||||
// For compatibility with whoever thought it would be
|
||||
// a good idea to access internal APIs through reflection
|
||||
// (e.g. MonoGame)
|
||||
public IntPtr WindowHandle { get { return Handle; } set { Handle = value; } }
|
||||
|
||||
public GetInt XOffset { get; set; }
|
||||
|
||||
public GetInt YOffset { get; set; }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
if (disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
if (ownHandle)
|
||||
{
|
||||
Handle = IntPtr.Zero;
|
||||
}
|
||||
|
||||
disposed = true;
|
||||
}
|
||||
|
||||
~CarbonWindowInfo()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
97
GLWidget/OpenTK/Platform/MacOS/Cocoa/Class.cs
Normal file
97
GLWidget/OpenTK/Platform/MacOS/Cocoa/Class.cs
Normal file
|
@ -0,0 +1,97 @@
|
|||
//
|
||||
// Class.cs
|
||||
//
|
||||
// Author:
|
||||
// Olle Håkansson <ollhak@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2014 Olle Håkansson
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
using System;
|
||||
|
||||
namespace OpenTK.Platform.MacOS
|
||||
{
|
||||
internal static class Class
|
||||
{
|
||||
public static readonly IntPtr NSAutoreleasePool = Get("NSAutoreleasePool");
|
||||
public static readonly IntPtr NSDictionary = Get("NSDictionary");
|
||||
public static readonly IntPtr NSNumber = Get("NSNumber");
|
||||
public static readonly IntPtr NSUserDefaults = Get("NSUserDefaults");
|
||||
|
||||
[DllImport (Cocoa.LibObjC)]
|
||||
private extern static IntPtr class_getName(IntPtr handle);
|
||||
|
||||
[DllImport (Cocoa.LibObjC)]
|
||||
private extern static bool class_addMethod(IntPtr classHandle, IntPtr selector, IntPtr method, string types);
|
||||
|
||||
[DllImport (Cocoa.LibObjC)]
|
||||
private extern static IntPtr objc_getClass(string name);
|
||||
|
||||
[DllImport (Cocoa.LibObjC)]
|
||||
private extern static IntPtr objc_allocateClassPair(IntPtr parentClass, string name, int extraBytes);
|
||||
|
||||
[DllImport (Cocoa.LibObjC)]
|
||||
private extern static void objc_registerClassPair(IntPtr classToRegister);
|
||||
|
||||
[DllImport (Cocoa.LibObjC)]
|
||||
private extern static void objc_disposeClassPair(IntPtr cls);
|
||||
|
||||
public static IntPtr Get(string name)
|
||||
{
|
||||
var id = objc_getClass(name);
|
||||
if (id == IntPtr.Zero)
|
||||
{
|
||||
throw new ArgumentException("Unknown class: " + name);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
public static IntPtr AllocateClass(string className, string parentClass)
|
||||
{
|
||||
return objc_allocateClassPair(Get(parentClass), className, 0);
|
||||
}
|
||||
|
||||
public static void RegisterClass(IntPtr handle)
|
||||
{
|
||||
objc_registerClassPair(handle);
|
||||
}
|
||||
|
||||
public static void DisposeClass(IntPtr handle)
|
||||
{
|
||||
objc_disposeClassPair(handle);
|
||||
}
|
||||
|
||||
public static void RegisterMethod(IntPtr handle, Delegate d, string selector, string typeString)
|
||||
{
|
||||
// TypeString info:
|
||||
// https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html
|
||||
|
||||
IntPtr p = Marshal.GetFunctionPointerForDelegate(d);
|
||||
bool r = class_addMethod(handle, Selector.Get(selector), p, typeString);
|
||||
|
||||
if (!r)
|
||||
{
|
||||
throw new ArgumentException("Could not register method " + d + " in class + " + class_getName(handle));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
284
GLWidget/OpenTK/Platform/MacOS/Cocoa/Cocoa.cs
Normal file
284
GLWidget/OpenTK/Platform/MacOS/Cocoa/Cocoa.cs
Normal file
|
@ -0,0 +1,284 @@
|
|||
//
|
||||
// Cocoa.cs
|
||||
//
|
||||
// Author:
|
||||
// Olle Håkansson <ollhak@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2014 Olle Håkansson
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
|
||||
namespace OpenTK.Platform.MacOS
|
||||
{
|
||||
internal static class Cocoa
|
||||
{
|
||||
private static readonly IntPtr selUTF8String = Selector.Get("UTF8String");
|
||||
|
||||
internal const string LibObjC = "/usr/lib/libobjc.dylib";
|
||||
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||
public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector);
|
||||
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||
public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, ulong ulong1);
|
||||
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||
public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, NSSize size);
|
||||
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||
public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, IntPtr intPtr1);
|
||||
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||
public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, IntPtr intPtr1, int int1);
|
||||
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||
public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, IntPtr intPtr1, IntPtr intPtr2);
|
||||
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||
public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, IntPtr intPtr1, IntPtr intPtr2, IntPtr intPtr3);
|
||||
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||
public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, IntPtr intPtr1, IntPtr intPtr2, IntPtr intPtr3, IntPtr intPtr4, IntPtr intPtr5);
|
||||
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||
public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, IntPtr p1, NSPoint p2);
|
||||
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||
public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, bool p1);
|
||||
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||
public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, NSPoint p1);
|
||||
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||
public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, NSRect rectangle1);
|
||||
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||
public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, NSRect rectangle1, int int1, int int2, bool bool1);
|
||||
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||
public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, uint uint1, IntPtr intPtr1, IntPtr intPtr2, bool bool1);
|
||||
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||
public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, NSRect rectangle1, int int1, IntPtr intPtr1, IntPtr intPtr2);
|
||||
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||
public extern static IntPtr SendIntPtr(IntPtr receiver, IntPtr selector, IntPtr p1, int p2, int p3, int p4, int p5, int p6, int p7, IntPtr p8, NSBitmapFormat p9, int p10, int p11);
|
||||
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||
public extern static bool SendBool(IntPtr receiver, IntPtr selector);
|
||||
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||
public extern static bool SendBool(IntPtr receiver, IntPtr selector, int int1);
|
||||
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||
public extern static void SendVoid(IntPtr receiver, IntPtr selector);
|
||||
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||
public extern static void SendVoid(IntPtr receiver, IntPtr selector, uint uint1);
|
||||
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||
public extern static void SendVoid(IntPtr receiver, IntPtr selector, uint uint1, IntPtr intPtr1);
|
||||
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||
public extern static void SendVoid(IntPtr receiver, IntPtr selector, IntPtr intPtr1);
|
||||
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||
public extern static void SendVoid(IntPtr receiver, IntPtr selector, IntPtr intPtr1, int int1);
|
||||
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||
public extern static void SendVoid(IntPtr receiver, IntPtr selector, IntPtr intPtr1, IntPtr intPtr2);
|
||||
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||
public extern static void SendVoid(IntPtr receiver, IntPtr selector, int int1);
|
||||
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||
public extern static void SendVoid(IntPtr receiver, IntPtr selector, bool bool1);
|
||||
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||
public extern static void SendVoid(IntPtr receiver, IntPtr selector, NSPoint point1);
|
||||
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||
public extern static void SendVoid(IntPtr receiver, IntPtr selector, NSRect rect1, bool bool1);
|
||||
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||
public extern static void SendVoid(IntPtr receiver, IntPtr selector, NSRect rect1, IntPtr intPtr1);
|
||||
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||
public extern static int SendInt(IntPtr receiver, IntPtr selector);
|
||||
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||
public extern static uint SendUint(IntPtr receiver, IntPtr selector);
|
||||
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||
public extern static ushort SendUshort(IntPtr receiver, IntPtr selector);
|
||||
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend_fpret")]
|
||||
private extern static float SendFloat_i386(IntPtr receiver, IntPtr selector);
|
||||
|
||||
// On x64 using selector that return CGFloat give you 64 bit == double
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||
private extern static double SendFloat_x64(IntPtr receiver, IntPtr selector);
|
||||
|
||||
[DllImport(LibObjC, EntryPoint="objc_msgSend")]
|
||||
private extern static float SendFloat_ios(IntPtr receiver, IntPtr selector);
|
||||
|
||||
public static float SendFloat(IntPtr receiver, IntPtr selector)
|
||||
{
|
||||
if (IntPtr.Size == 4)
|
||||
{
|
||||
return SendFloat_i386(receiver, selector);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (float)SendFloat_x64(receiver, selector);
|
||||
}
|
||||
}
|
||||
|
||||
// Not the _stret version, perhaps because a NSPoint fits in one register?
|
||||
// thefiddler: gcc is indeed using objc_msgSend for NSPoint on i386
|
||||
[DllImport (LibObjC, EntryPoint="objc_msgSend")]
|
||||
public extern static NSPointF SendPointF(IntPtr receiver, IntPtr selector);
|
||||
[DllImport (LibObjC, EntryPoint="objc_msgSend")]
|
||||
public extern static NSPointD SendPointD(IntPtr receiver, IntPtr selector);
|
||||
|
||||
public static NSPoint SendPoint(IntPtr receiver, IntPtr selector)
|
||||
{
|
||||
NSPoint r = new NSPoint();
|
||||
|
||||
unsafe
|
||||
{
|
||||
if (IntPtr.Size == 4)
|
||||
{
|
||||
NSPointF pf = SendPointF(receiver, selector);
|
||||
r.X.Value = *(IntPtr *)&pf.X;
|
||||
r.Y.Value = *(IntPtr *)&pf.Y;
|
||||
}
|
||||
else
|
||||
{
|
||||
NSPointD pd = SendPointD(receiver, selector);
|
||||
r.X.Value = *(IntPtr *)&pd.X;
|
||||
r.Y.Value = *(IntPtr *)&pd.Y;
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
[DllImport (LibObjC, EntryPoint="objc_msgSend_stret")]
|
||||
private extern static void SendRect(out NSRect retval, IntPtr receiver, IntPtr selector);
|
||||
|
||||
[DllImport (LibObjC, EntryPoint="objc_msgSend_stret")]
|
||||
private extern static void SendRect(out NSRect retval, IntPtr receiver, IntPtr selector, NSRect rect1);
|
||||
|
||||
public static NSRect SendRect(IntPtr receiver, IntPtr selector)
|
||||
{
|
||||
NSRect r;
|
||||
SendRect(out r, receiver, selector);
|
||||
return r;
|
||||
}
|
||||
|
||||
public static NSRect SendRect(IntPtr receiver, IntPtr selector, NSRect rect1)
|
||||
{
|
||||
NSRect r;
|
||||
SendRect(out r, receiver, selector, rect1);
|
||||
return r;
|
||||
}
|
||||
|
||||
public static IntPtr ToNSString(string str)
|
||||
{
|
||||
if (str == null)
|
||||
{
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
unsafe
|
||||
{
|
||||
fixed (char* ptrFirstChar = str)
|
||||
{
|
||||
var handle = Cocoa.SendIntPtr(Class.Get("NSString"), Selector.Alloc);
|
||||
handle = Cocoa.SendIntPtr(handle, Selector.Get("initWithCharacters:length:"), (IntPtr)ptrFirstChar, str.Length);
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string FromNSString(IntPtr handle)
|
||||
{
|
||||
return Marshal.PtrToStringAuto(SendIntPtr(handle, selUTF8String));
|
||||
}
|
||||
|
||||
public static unsafe IntPtr ToNSImage(Image img)
|
||||
{
|
||||
using (System.IO.MemoryStream s = new System.IO.MemoryStream())
|
||||
{
|
||||
img.Save(s, ImageFormat.Png);
|
||||
byte[] b = s.ToArray();
|
||||
|
||||
fixed (byte* pBytes = b)
|
||||
{
|
||||
IntPtr nsData = Cocoa.SendIntPtr(Cocoa.SendIntPtr(Class.Get("NSData"), Selector.Alloc),
|
||||
Selector.Get("initWithBytes:length:"), (IntPtr)pBytes, b.Length);
|
||||
|
||||
IntPtr nsImage = Cocoa.SendIntPtr(Cocoa.SendIntPtr(Class.Get("NSImage"), Selector.Alloc),
|
||||
Selector.Get("initWithData:"), nsData);
|
||||
|
||||
Cocoa.SendVoid(nsData, Selector.Release);
|
||||
return nsImage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static IntPtr GetStringConstant(IntPtr handle, string symbol)
|
||||
{
|
||||
var indirect = NS.GetSymbol(handle, symbol);
|
||||
if (indirect == IntPtr.Zero)
|
||||
{
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
var actual = Marshal.ReadIntPtr(indirect);
|
||||
if (actual == IntPtr.Zero)
|
||||
{
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
return actual;
|
||||
}
|
||||
|
||||
public static IntPtr AppKitLibrary;
|
||||
public static IntPtr FoundationLibrary;
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
if (AppKitLibrary != IntPtr.Zero)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AppKitLibrary = NS.LoadLibrary("/System/Library/Frameworks/AppKit.framework/AppKit");
|
||||
FoundationLibrary = NS.LoadLibrary("/System/Library/Frameworks/Foundation.framework/Foundation");
|
||||
}
|
||||
}
|
||||
}
|
138
GLWidget/OpenTK/Platform/MacOS/Cocoa/NSApplication.cs
Normal file
138
GLWidget/OpenTK/Platform/MacOS/Cocoa/NSApplication.cs
Normal file
|
@ -0,0 +1,138 @@
|
|||
//
|
||||
// NSApplication.cs
|
||||
//
|
||||
// Author:
|
||||
// Olle Håkansson <ollhak@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2014 Olle Håkansson
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
|
||||
namespace OpenTK.Platform.MacOS
|
||||
{
|
||||
internal static class NSApplication
|
||||
{
|
||||
internal static IntPtr Handle;
|
||||
|
||||
private static readonly IntPtr selQuit = Selector.Get("quit");
|
||||
|
||||
private static readonly int ThreadId =
|
||||
System.Threading.Thread.CurrentThread.ManagedThreadId;
|
||||
|
||||
internal static void Initialize() { }
|
||||
|
||||
static NSApplication()
|
||||
{
|
||||
Cocoa.Initialize();
|
||||
|
||||
// Register a Quit method to be called on cmd-q
|
||||
IntPtr nsapp = Class.Get("NSApplication");
|
||||
Class.RegisterMethod(nsapp, OnQuitHandler, "quit", "v@:");
|
||||
|
||||
// Fetch the application handle
|
||||
Handle = Cocoa.SendIntPtr(nsapp, Selector.Get("sharedApplication"));
|
||||
|
||||
// Setup the application
|
||||
Cocoa.SendBool(Handle, Selector.Get("setActivationPolicy:"), (int)NSApplicationActivationPolicy.Regular);
|
||||
Cocoa.SendVoid(Handle, Selector.Get("discardEventsMatchingMask:beforeEvent:"), uint.MaxValue, IntPtr.Zero);
|
||||
Cocoa.SendVoid(Handle, Selector.Get("activateIgnoringOtherApps:"), true);
|
||||
|
||||
if (Cocoa.SendIntPtr(Handle, Selector.Get("mainMenu")) == IntPtr.Zero)
|
||||
{
|
||||
// Create the menu bar
|
||||
var menubar = Cocoa.SendIntPtr(Class.Get("NSMenu"), Selector.Alloc);
|
||||
var menuItem = Cocoa.SendIntPtr(Class.Get("NSMenuItem"), Selector.Alloc);
|
||||
|
||||
// Add menu item to bar, and bar to application
|
||||
Cocoa.SendIntPtr(menubar, Selector.Get("addItem:"), menuItem);
|
||||
Cocoa.SendIntPtr(Handle, Selector.Get("setMainMenu:"), menubar);
|
||||
|
||||
// Add a "Quit" menu item and bind the button.
|
||||
var appMenu = Cocoa.SendIntPtr(Class.Get("NSMenu"), Selector.Alloc);
|
||||
var quitMenuItem = Cocoa.SendIntPtr(Cocoa.SendIntPtr(Class.Get("NSMenuItem"), Selector.Alloc),
|
||||
Selector.Get("initWithTitle:action:keyEquivalent:"), Cocoa.ToNSString("Quit"), selQuit, Cocoa.ToNSString("q"));
|
||||
|
||||
Cocoa.SendIntPtr(appMenu, Selector.Get("addItem:"), quitMenuItem);
|
||||
Cocoa.SendIntPtr(menuItem, Selector.Get("setSubmenu:"), appMenu);
|
||||
|
||||
// Tell cocoa we're ready to run the application (usually called by [NSApp run]).
|
||||
// Note: if a main menu exists, then this method has already been called and
|
||||
// calling it again will result in a crash. For this reason, we only call it
|
||||
// when we create our own main menu.
|
||||
Cocoa.SendVoid(Handle, Selector.Get("finishLaunching"));
|
||||
}
|
||||
|
||||
// Disable momentum scrolling and long-press key pop-ups
|
||||
IntPtr settings = Cocoa.SendIntPtr(Class.NSDictionary, Selector.Alloc);
|
||||
//IntPtr momentum_scrolling = Cocoa.SendIntPtr(Class.NSNumber, Selector.Get("numberWithBool:"), false);
|
||||
IntPtr press_and_hold = Cocoa.SendIntPtr(Class.NSNumber, Selector.Get("numberWithBool:"), false);
|
||||
|
||||
// Initialize and register the settings dictionary
|
||||
settings =
|
||||
Cocoa.SendIntPtr(settings, Selector.Get("initWithObjectsAndKeys:"),
|
||||
//momentum_scrolling, Cocoa.ToNSString("AppleMomentumScrollSupported"),
|
||||
press_and_hold, Cocoa.ToNSString("ApplePressAndHoldEnabled"),
|
||||
IntPtr.Zero);
|
||||
Cocoa.SendVoid(
|
||||
Cocoa.SendIntPtr(Class.NSUserDefaults, Selector.Get("standardUserDefaults")),
|
||||
Selector.Get("registerDefaults:"),
|
||||
settings);
|
||||
Cocoa.SendVoid(settings, Selector.Release);
|
||||
}
|
||||
|
||||
internal static bool IsUIThread
|
||||
{
|
||||
get
|
||||
{
|
||||
int thread_id = Thread.CurrentThread.ManagedThreadId;
|
||||
bool is_ui_thread = thread_id == NSApplication.ThreadId;
|
||||
if (!is_ui_thread)
|
||||
{
|
||||
Debug.Print("[Warning] UI resources must be disposed in the UI thread #{0}, not #{1}.",
|
||||
NSApplication.ThreadId, thread_id);
|
||||
}
|
||||
return is_ui_thread;
|
||||
}
|
||||
}
|
||||
|
||||
internal static event EventHandler<CancelEventArgs> Quit = delegate { };
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
|
||||
private delegate void OnQuitDelegate(IntPtr self, IntPtr cmd);
|
||||
|
||||
private static OnQuitDelegate OnQuitHandler = OnQuit;
|
||||
|
||||
private static void OnQuit(IntPtr self, IntPtr cmd)
|
||||
{
|
||||
var e = new CancelEventArgs();
|
||||
Quit(null, e);
|
||||
if (!e.Cancel)
|
||||
{
|
||||
Cocoa.SendVoid(Handle, Selector.Get("terminate:"), Handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
//
|
||||
// NSApplicationActivationPolicy.cs
|
||||
//
|
||||
// Author:
|
||||
// Olle Håkansson <ollhak@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2014 Olle Håkansson
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
namespace OpenTK.Platform.MacOS
|
||||
{
|
||||
internal enum NSApplicationActivationPolicy
|
||||
{
|
||||
Regular,
|
||||
Accessory,
|
||||
Prohibited,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
//
|
||||
// NSApplicationPresentationOptions.cs
|
||||
//
|
||||
// Author:
|
||||
// Olle Håkansson <ollhak@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2014 Olle Håkansson
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
namespace OpenTK.Platform.MacOS
|
||||
{
|
||||
internal enum NSApplicationPresentationOptions
|
||||
{
|
||||
Default = 0,
|
||||
AutoHideDock = 1,
|
||||
HideDock = 2,
|
||||
AutoHideMenuBar = 4,
|
||||
HideMenuBar = 8,
|
||||
DisableAppleMenu = 16,
|
||||
DisableProcessSwitching = 32,
|
||||
DisableForceQuit = 64,
|
||||
DisableSessionTermination = 128,
|
||||
DisableHideApplication = 256,
|
||||
DisableMenuBarTransparency = 512,
|
||||
FullScreen = 1024,
|
||||
AutoHideToolbar = 2048,
|
||||
}
|
||||
}
|
34
GLWidget/OpenTK/Platform/MacOS/Cocoa/NSAutoreleasePool.cs
Normal file
34
GLWidget/OpenTK/Platform/MacOS/Cocoa/NSAutoreleasePool.cs
Normal file
|
@ -0,0 +1,34 @@
|
|||
using System;
|
||||
|
||||
namespace OpenTK.Platform.MacOS
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="NSAutoreleasePool"/> class is a wrapper around the native objective-C NSAutoreleasePool.
|
||||
/// In particular, this construct mimics the usage of an @autorelease block and can be used in much the same way,
|
||||
/// only with a C# using block instead.
|
||||
/// </summary>
|
||||
public sealed class NSAutoreleasePool : IDisposable
|
||||
{
|
||||
private readonly IntPtr _autoreleasePool;
|
||||
|
||||
/// <summary>
|
||||
/// Allocates and initializes a new <see cref="NSAutoreleasePool"/>.
|
||||
/// </summary>
|
||||
public NSAutoreleasePool()
|
||||
{
|
||||
var uninitializedPool = Cocoa.SendIntPtr(Class.NSAutoreleasePool, Selector.Alloc);
|
||||
_autoreleasePool = Cocoa.SendIntPtr(uninitializedPool, Selector.Init);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes of the <see cref="NSAutoreleasePool"/> instance, draining it.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
if (_autoreleasePool != IntPtr.Zero)
|
||||
{
|
||||
Cocoa.SendVoid(_autoreleasePool, Selector.Get("drain"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
36
GLWidget/OpenTK/Platform/MacOS/Cocoa/NSBackingStore.cs
Normal file
36
GLWidget/OpenTK/Platform/MacOS/Cocoa/NSBackingStore.cs
Normal file
|
@ -0,0 +1,36 @@
|
|||
//
|
||||
// NSBackingStore.cs
|
||||
//
|
||||
// Author:
|
||||
// Olle Håkansson <ollhak@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2014 Olle Håkansson
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
namespace OpenTK.Platform.MacOS
|
||||
{
|
||||
internal enum NSBackingStore
|
||||
{
|
||||
Retained,
|
||||
Nonretained,
|
||||
Buffered,
|
||||
}
|
||||
}
|
40
GLWidget/OpenTK/Platform/MacOS/Cocoa/NSBitmapFormat.cs
Normal file
40
GLWidget/OpenTK/Platform/MacOS/Cocoa/NSBitmapFormat.cs
Normal file
|
@ -0,0 +1,40 @@
|
|||
//
|
||||
// NSBitmapFormat.cs
|
||||
//
|
||||
// Author:
|
||||
// Stefanos A. <stapostol@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2006-2014 Stefanos Apostolopoulos
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
|
||||
namespace OpenTK.Platform.MacOS
|
||||
{
|
||||
[Flags]
|
||||
internal enum NSBitmapFormat
|
||||
{
|
||||
AlphaFirst = 1 << 0,
|
||||
AlphaNonpremultiplied = 1 << 1,
|
||||
FloatingPointSamples = 1 << 2
|
||||
}
|
||||
}
|
||||
|
23
GLWidget/OpenTK/Platform/MacOS/Cocoa/NSDragOperation.cs
Normal file
23
GLWidget/OpenTK/Platform/MacOS/Cocoa/NSDragOperation.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
|
||||
namespace OpenTK.Platform.MacOS
|
||||
{
|
||||
/// <summary>
|
||||
/// Used by draggingSourceOperationMask() <see cref="CocoaNativeWindow.DraggingEntered"/> to get permission for dropped object
|
||||
/// also used for respones to drag source
|
||||
/// Values for enum can be found here https://developer.apple.com/documentation/appkit/nsdragoperation?language=objc
|
||||
/// or for Mac users /System/Library/Frameworks/AppKit.framework/Headers
|
||||
/// </summary>
|
||||
internal enum NSDragOperation : int
|
||||
{
|
||||
None = 0,
|
||||
Copy = 1,
|
||||
Link = 2,
|
||||
Generic = 4,
|
||||
Private = 8,
|
||||
AllObsolete = 15,
|
||||
Move = 16,
|
||||
Delete = 32,
|
||||
Every = Int32.MaxValue,
|
||||
}
|
||||
}
|
45
GLWidget/OpenTK/Platform/MacOS/Cocoa/NSEventModifierMask.cs
Normal file
45
GLWidget/OpenTK/Platform/MacOS/Cocoa/NSEventModifierMask.cs
Normal file
|
@ -0,0 +1,45 @@
|
|||
//
|
||||
// NSEventModifierMask.cs
|
||||
//
|
||||
// Author:
|
||||
// Olle Håkansson <ollhak@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2014 Olle Håkansson
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
|
||||
namespace OpenTK.Platform.MacOS
|
||||
{
|
||||
[Flags]
|
||||
internal enum NSEventModifierMask : uint
|
||||
{
|
||||
AlphaShiftKeyMask = 65536U,
|
||||
ShiftKeyMask = 131072U,
|
||||
ControlKeyMask = 262144U,
|
||||
AlternateKeyMask = 524288U,
|
||||
CommandKeyMask = 1048576U,
|
||||
NumericPadKeyMask = 2097152U,
|
||||
HelpKeyMask = 4194304U,
|
||||
FunctionKeyMask = 8388608U,
|
||||
DeviceIndependentModifierFlagsMask = 4294901760U,
|
||||
}
|
||||
}
|
64
GLWidget/OpenTK/Platform/MacOS/Cocoa/NSEventType.cs
Normal file
64
GLWidget/OpenTK/Platform/MacOS/Cocoa/NSEventType.cs
Normal file
|
@ -0,0 +1,64 @@
|
|||
//
|
||||
// NSEventType.cs
|
||||
//
|
||||
// Author:
|
||||
// Olle Håkansson <ollhak@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2014 Olle Håkansson
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
namespace OpenTK.Platform.MacOS
|
||||
{
|
||||
internal enum NSEventType
|
||||
{
|
||||
LeftMouseDown = 1,
|
||||
LeftMouseUp = 2,
|
||||
RightMouseDown = 3,
|
||||
RightMouseUp = 4,
|
||||
MouseMoved = 5,
|
||||
LeftMouseDragged = 6,
|
||||
RightMouseDragged = 7,
|
||||
MouseEntered = 8,
|
||||
MouseExited = 9,
|
||||
KeyDown = 10,
|
||||
KeyUp = 11,
|
||||
FlagsChanged = 12,
|
||||
AppKitDefined = 13,
|
||||
SystemDefined = 14,
|
||||
ApplicationDefined = 15,
|
||||
Periodic = 16,
|
||||
CursorUpdate = 17,
|
||||
Rotate = 18,
|
||||
BeginGesture = 19,
|
||||
EndGesture = 20,
|
||||
ScrollWheel = 22,
|
||||
TabletPoint = 23,
|
||||
TabletProximity = 24,
|
||||
OtherMouseDown = 25,
|
||||
OtherMouseUp = 26,
|
||||
OtherMouseDragged = 27,
|
||||
Gesture = 29,
|
||||
Magnify = 30,
|
||||
Swipe = 31,
|
||||
SmartMagnify = 32,
|
||||
QuickLook = 33,
|
||||
}
|
||||
}
|
201
GLWidget/OpenTK/Platform/MacOS/Cocoa/NSFloat.cs
Normal file
201
GLWidget/OpenTK/Platform/MacOS/Cocoa/NSFloat.cs
Normal file
|
@ -0,0 +1,201 @@
|
|||
//
|
||||
// NSFloat.cs
|
||||
//
|
||||
// Author:
|
||||
// Stefanos A. <stapostol@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2006-2014 Stefanos Apostolopoulos
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OpenTK.Platform.MacOS
|
||||
{
|
||||
// NSFloat is defined as float on 32bit systems and double on 64bit.
|
||||
// We have to account for this peculiarity in order to run OpenTK on
|
||||
// 64bit Mac platforms.
|
||||
// We do this by adding implicit conversions between IntPtr and float/double.
|
||||
// Note that this conversion is against C# best practices, as it can lose information.
|
||||
// However, NSFloat is used internally in places where this precision loss does not matter.
|
||||
internal struct NSFloat
|
||||
{
|
||||
private IntPtr _value;
|
||||
|
||||
public IntPtr Value
|
||||
{
|
||||
get { return _value; }
|
||||
set { _value = value; }
|
||||
}
|
||||
|
||||
public static implicit operator NSFloat(float v)
|
||||
{
|
||||
NSFloat f = new NSFloat();
|
||||
unsafe
|
||||
{
|
||||
if (IntPtr.Size == 4)
|
||||
{
|
||||
f.Value = *(IntPtr*)&v;
|
||||
}
|
||||
else
|
||||
{
|
||||
double d = v;
|
||||
f.Value = *(IntPtr*)&d;
|
||||
}
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
public static implicit operator NSFloat(double v)
|
||||
{
|
||||
NSFloat f = new NSFloat();
|
||||
unsafe
|
||||
{
|
||||
if (IntPtr.Size == 4)
|
||||
{
|
||||
float fv = (float)v;
|
||||
f.Value = *(IntPtr*)&fv;
|
||||
}
|
||||
else
|
||||
{
|
||||
f.Value = *(IntPtr*)&v;
|
||||
}
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
public static implicit operator float(NSFloat f)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (IntPtr.Size == 4)
|
||||
{
|
||||
return *(float*)&f._value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (float)*(double*)&f._value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static implicit operator double(NSFloat f)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if (IntPtr.Size == 4)
|
||||
{
|
||||
return (double)*(float*)&f._value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return *(double*)&f._value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct NSPoint
|
||||
{
|
||||
public NSFloat X;
|
||||
public NSFloat Y;
|
||||
|
||||
public static implicit operator NSPoint(PointF p)
|
||||
{
|
||||
return new NSPoint
|
||||
{
|
||||
X = p.X,
|
||||
Y = p.Y
|
||||
};
|
||||
}
|
||||
|
||||
public static implicit operator PointF(NSPoint s)
|
||||
{
|
||||
return new PointF(s.X, s.Y);
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct NSSize
|
||||
{
|
||||
public NSFloat Width;
|
||||
public NSFloat Height;
|
||||
|
||||
public static implicit operator NSSize(SizeF s)
|
||||
{
|
||||
return new NSSize
|
||||
{
|
||||
Width = s.Width,
|
||||
Height = s.Height
|
||||
};
|
||||
}
|
||||
|
||||
public static implicit operator SizeF(NSSize s)
|
||||
{
|
||||
return new SizeF(s.Width, s.Height);
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct NSRect
|
||||
{
|
||||
public NSPoint Location;
|
||||
public NSSize Size;
|
||||
|
||||
public NSFloat Width { get { return Size.Width; } }
|
||||
public NSFloat Height { get { return Size.Height; } }
|
||||
public NSFloat X { get { return Location.X; } }
|
||||
public NSFloat Y { get { return Location.Y; } }
|
||||
|
||||
public static implicit operator NSRect(RectangleF s)
|
||||
{
|
||||
return new NSRect
|
||||
{
|
||||
Location = s.Location,
|
||||
Size = s.Size
|
||||
};
|
||||
}
|
||||
|
||||
public static implicit operator RectangleF(NSRect s)
|
||||
{
|
||||
return new RectangleF(s.Location, s.Size);
|
||||
}
|
||||
}
|
||||
|
||||
// Using IntPtr in NSFloat cause that if imported function
|
||||
// return struct that consist of them you will get wrong data
|
||||
// This types are used for such function.
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct NSPointF
|
||||
{
|
||||
public float X;
|
||||
public float Y;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct NSPointD
|
||||
{
|
||||
public double X;
|
||||
public double Y;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
//
|
||||
// NSOpenGLContextParameter.cs
|
||||
//
|
||||
// Author:
|
||||
// Olle Håkansson <ollhak@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2014 Olle Håkansson
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
|
||||
namespace OpenTK.Platform.MacOS
|
||||
{
|
||||
internal enum NSOpenGLContextParameter
|
||||
{
|
||||
[Obsolete] SwapRectangle = 200,
|
||||
[Obsolete] SwapRectangleEnable = 201,
|
||||
[Obsolete] RasterizationEnable = 221,
|
||||
SwapInterval = 222,
|
||||
SurfaceOrder = 235,
|
||||
SurfaceOpacity = 236,
|
||||
[Obsolete] StateValidation = 301,
|
||||
SurfaceBackingSize = 304, // Lion
|
||||
[Obsolete] SurfaceSurfaceVolatile = 306,
|
||||
ReclaimResources = 308, // Lion
|
||||
CurrentRendererID = 309, // Lion
|
||||
GpuVertexProcessing = 310, // Lion
|
||||
GpuFragmentProcessing = 311, // Lion
|
||||
HasDrawable = 314, // Lion
|
||||
MpsSwapsInFlight = 315, // Lion
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
//
|
||||
// NSOpenGLPixelFormatAttribute.cs
|
||||
//
|
||||
// Author:
|
||||
// Olle Håkansson <ollhak@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2014 Olle Håkansson
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
|
||||
namespace OpenTK.Platform.MacOS
|
||||
{
|
||||
internal enum NSOpenGLPixelFormatAttribute
|
||||
{
|
||||
AllRenderers = 1,
|
||||
TrippleBuffer = 3, // Lion
|
||||
DoubleBuffer = 5,
|
||||
Stereo = 6,
|
||||
AuxBuffers = 7,
|
||||
ColorSize = 8,
|
||||
AlphaSize = 11,
|
||||
DepthSize = 12,
|
||||
StencilSize = 13,
|
||||
AccumSize = 14,
|
||||
MinimumPolicy = 51,
|
||||
MaximumPolicy = 52,
|
||||
OffScreen = 53,
|
||||
FullScreen = 54,
|
||||
SampleBuffers = 55,
|
||||
Samples = 56,
|
||||
AuxDepthStencil = 57,
|
||||
ColorFloat = 58,
|
||||
Multisample = 59,
|
||||
Supersample = 60,
|
||||
SampleAlpha = 61,
|
||||
RendererID = 70,
|
||||
SingleRenderer = 71,
|
||||
NoRecovery = 72,
|
||||
Accelerated = 73,
|
||||
ClosestPolicy = 74,
|
||||
[Obsolete] Robust = 75,
|
||||
BackingStore = 76,
|
||||
[Obsolete] MPSafe = 78,
|
||||
Window = 80,
|
||||
[Obsolete] MultiScreen = 81,
|
||||
Compliant = 83,
|
||||
ScreenMask = 84,
|
||||
PixelBuffer = 90,
|
||||
RemotePixelBuffer = 91,
|
||||
AllowOfflineRenderers = 96,
|
||||
AcceleratedCompute = 97,
|
||||
OpenGLProfile = 99, // Lion
|
||||
VirtualScreenCount = 128,
|
||||
}
|
||||
}
|
35
GLWidget/OpenTK/Platform/MacOS/Cocoa/NSOpenGLProfile.cs
Normal file
35
GLWidget/OpenTK/Platform/MacOS/Cocoa/NSOpenGLProfile.cs
Normal file
|
@ -0,0 +1,35 @@
|
|||
//
|
||||
// NSOpenGLProfile.cs
|
||||
//
|
||||
// Author:
|
||||
// Olle Håkansson <ollhak@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2014 Olle Håkansson
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
namespace OpenTK.Platform.MacOS
|
||||
{
|
||||
internal enum NSOpenGLProfile
|
||||
{
|
||||
VersionLegacy = 4096,
|
||||
Version3_2Core = 12800,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
//
|
||||
// NSTrackingAreaOptions.cs
|
||||
//
|
||||
// Author:
|
||||
// Olle Håkansson <ollhak@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2014 Olle Håkansson
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
|
||||
namespace OpenTK.Platform.MacOS
|
||||
{
|
||||
[Flags]
|
||||
internal enum NSTrackingAreaOptions
|
||||
{
|
||||
MouseEnteredAndExited = 1,
|
||||
MouseMoved = 2,
|
||||
CursorUpdate = 4,
|
||||
ActiveWhenFirstResponder = 16,
|
||||
ActiveInKeyWindow = 32,
|
||||
ActiveInActiveApp = 64,
|
||||
ActiveAlways = 128,
|
||||
AssumeInside = 256,
|
||||
InVisibleRect = 512,
|
||||
EnabledDuringMouseDrag = 1024,
|
||||
}
|
||||
}
|
49
GLWidget/OpenTK/Platform/MacOS/Cocoa/NSWindowStyle.cs
Normal file
49
GLWidget/OpenTK/Platform/MacOS/Cocoa/NSWindowStyle.cs
Normal file
|
@ -0,0 +1,49 @@
|
|||
//
|
||||
// NSWindowStyle.cs
|
||||
//
|
||||
// Author:
|
||||
// Olle Håkansson <ollhak@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2014 Olle Håkansson
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
|
||||
namespace OpenTK.Platform.MacOS
|
||||
{
|
||||
[Flags]
|
||||
internal enum NSWindowStyle
|
||||
{
|
||||
Borderless = 0,
|
||||
Titled = 1,
|
||||
Closable = 2,
|
||||
Miniaturizable = 4,
|
||||
Resizable = 8,
|
||||
Utility = 16,
|
||||
DocModal = 64,
|
||||
NonactivatingPanel = 128,
|
||||
TexturedBackground = 256,
|
||||
Unscaled = 2048,
|
||||
UnifiedTitleAndToolbar = 4096,
|
||||
Hud = 8192,
|
||||
FullScreenWindow = 16384,
|
||||
}
|
||||
}
|
46
GLWidget/OpenTK/Platform/MacOS/Cocoa/Selector.cs
Normal file
46
GLWidget/OpenTK/Platform/MacOS/Cocoa/Selector.cs
Normal file
|
@ -0,0 +1,46 @@
|
|||
//
|
||||
// Selector.cs
|
||||
//
|
||||
// Author:
|
||||
// Olle Håkansson <ollhak@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2014 Olle Håkansson
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OpenTK.Platform.MacOS
|
||||
{
|
||||
internal static class Selector
|
||||
{
|
||||
// Frequently used selectors
|
||||
public static readonly IntPtr Init = Selector.Get("init");
|
||||
public static readonly IntPtr InitWithCoder = Selector.Get("initWithCoder:");
|
||||
public static readonly IntPtr Alloc = Selector.Get("alloc");
|
||||
public static readonly IntPtr Retain = Selector.Get("retain");
|
||||
public static readonly IntPtr Release = Selector.Get("release");
|
||||
public static readonly IntPtr Autorelease = Selector.Get("autorelease");
|
||||
|
||||
[DllImport ("/usr/lib/libobjc.dylib", EntryPoint="sel_registerName")]
|
||||
public extern static IntPtr Get(string name);
|
||||
}
|
||||
}
|
410
GLWidget/OpenTK/Platform/MacOS/CocoaContext.cs
Normal file
410
GLWidget/OpenTK/Platform/MacOS/CocoaContext.cs
Normal file
|
@ -0,0 +1,410 @@
|
|||
//
|
||||
// CocoaContext.cs
|
||||
//
|
||||
// Author:
|
||||
// Olle Håkansson <ollhak@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2014 Olle Håkansson
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using OpenTK.Platform;
|
||||
using OpenTK.Graphics;
|
||||
using OpenTK.Platform.MacOS;
|
||||
using System.Diagnostics;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OpenTK
|
||||
{
|
||||
internal class CocoaContext : DesktopGraphicsContext
|
||||
{
|
||||
private CocoaWindowInfo cocoaWindow;
|
||||
private IntPtr shareContextRef;
|
||||
|
||||
private static readonly IntPtr NSOpenGLContext = Class.Get("NSOpenGLContext");
|
||||
private static readonly IntPtr selCurrentContext = Selector.Get("currentContext");
|
||||
private static readonly IntPtr selFlushBuffer = Selector.Get("flushBuffer");
|
||||
private static readonly IntPtr selMakeCurrentContext = Selector.Get("makeCurrentContext");
|
||||
private static readonly IntPtr selUpdate = Selector.Get("update");
|
||||
|
||||
private static readonly IntPtr opengl = NS.AddImage(
|
||||
"/System/Library/Frameworks/OpenGL.framework/OpenGL",
|
||||
AddImageFlags.ReturnOnError);
|
||||
|
||||
private static readonly IntPtr opengles = NS.AddImage(
|
||||
"/System/Library/Frameworks/OpenGL.framework/OpenGLES",
|
||||
AddImageFlags.ReturnOnError);
|
||||
|
||||
static CocoaContext()
|
||||
{
|
||||
Cocoa.Initialize();
|
||||
}
|
||||
|
||||
public CocoaContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, int majorVersion, int minorVersion)
|
||||
{
|
||||
Debug.Print("Context Type: {0}", shareContext);
|
||||
Debug.Print("Window info: {0}", window);
|
||||
|
||||
cocoaWindow = (CocoaWindowInfo)window;
|
||||
|
||||
if (shareContext is CocoaContext)
|
||||
{
|
||||
shareContextRef = ((CocoaContext)shareContext).Handle.Handle;
|
||||
}
|
||||
|
||||
if (shareContext is GraphicsContext)
|
||||
{
|
||||
ContextHandle shareHandle = shareContext != null ? (shareContext as IGraphicsContextInternal).Context : (ContextHandle)IntPtr.Zero;
|
||||
shareContextRef = shareHandle.Handle;
|
||||
}
|
||||
|
||||
if (shareContextRef == IntPtr.Zero)
|
||||
{
|
||||
Debug.Print("No context sharing will take place.");
|
||||
}
|
||||
|
||||
CreateContext(mode, cocoaWindow, shareContextRef, majorVersion, minorVersion, true);
|
||||
}
|
||||
|
||||
public CocoaContext(ContextHandle handle, IWindowInfo window, IGraphicsContext shareContext, int majorVersion, int minorVersion)
|
||||
{
|
||||
if (handle == ContextHandle.Zero)
|
||||
{
|
||||
throw new ArgumentException("handle");
|
||||
}
|
||||
if (window == null)
|
||||
{
|
||||
throw new ArgumentNullException("window");
|
||||
}
|
||||
|
||||
Handle = handle;
|
||||
cocoaWindow = (CocoaWindowInfo)window;
|
||||
}
|
||||
|
||||
private void AddPixelAttrib(List<NSOpenGLPixelFormatAttribute> attributes, NSOpenGLPixelFormatAttribute attribute)
|
||||
{
|
||||
Debug.Print(attribute.ToString());
|
||||
|
||||
attributes.Add(attribute);
|
||||
}
|
||||
|
||||
private void AddPixelAttrib(List<NSOpenGLPixelFormatAttribute> attributes, NSOpenGLPixelFormatAttribute attribute, int value)
|
||||
{
|
||||
Debug.Print("{0} : {1}", attribute, value);
|
||||
|
||||
attributes.Add(attribute);
|
||||
attributes.Add((NSOpenGLPixelFormatAttribute)value);
|
||||
}
|
||||
|
||||
private void CreateContext(GraphicsMode mode, CocoaWindowInfo cocoaWindow, IntPtr shareContextRef, int majorVersion, int minorVersion, bool fullscreen)
|
||||
{
|
||||
// Prepare attributes
|
||||
IntPtr pixelFormat = SelectPixelFormat(mode, majorVersion, minorVersion);
|
||||
if (pixelFormat == IntPtr.Zero)
|
||||
{
|
||||
throw new GraphicsException(String.Format(
|
||||
"Failed to contruct NSOpenGLPixelFormat for GraphicsMode '{0}'",
|
||||
mode));
|
||||
}
|
||||
|
||||
// Create context
|
||||
var context = Cocoa.SendIntPtr(NSOpenGLContext, Selector.Alloc);
|
||||
context = Cocoa.SendIntPtr(context, Selector.Get("initWithFormat:shareContext:"), pixelFormat, shareContextRef);
|
||||
if (context == IntPtr.Zero)
|
||||
{
|
||||
throw new GraphicsException(String.Format(
|
||||
"Failed to construct NSOpenGLContext",
|
||||
mode));
|
||||
}
|
||||
|
||||
// Release pixel format
|
||||
Cocoa.SendVoid(pixelFormat, Selector.Release);
|
||||
pixelFormat = IntPtr.Zero;
|
||||
|
||||
// Attach the view
|
||||
Cocoa.SendVoid(context, Selector.Get("setView:"), cocoaWindow.ViewHandle);
|
||||
Cocoa.SendVoid(cocoaWindow.ViewHandle, Selector.Get("setWantsBestResolutionOpenGLSurface:"), true);
|
||||
|
||||
// Finalize
|
||||
Handle = new ContextHandle(context);
|
||||
Mode = GetGraphicsMode(context);
|
||||
|
||||
Update(cocoaWindow);
|
||||
}
|
||||
|
||||
private IntPtr SelectPixelFormat(GraphicsMode mode, int majorVersion, int minorVersion)
|
||||
{
|
||||
List<NSOpenGLPixelFormatAttribute> attributes = new List<NSOpenGLPixelFormatAttribute>();
|
||||
|
||||
var profile = NSOpenGLProfile.VersionLegacy;
|
||||
if (majorVersion > 3 || (majorVersion == 3 && minorVersion >= 2))
|
||||
{
|
||||
profile = NSOpenGLProfile.Version3_2Core;
|
||||
Debug.Print("Running the OpenGL core profile.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Print("Running the legacy OpenGL profile. Start with version major=3, minor=2 or later for the 3.2 profile.");
|
||||
}
|
||||
|
||||
Debug.Print("NSGL pixel format attributes:");
|
||||
Debug.Indent();
|
||||
|
||||
AddPixelAttrib(attributes, NSOpenGLPixelFormatAttribute.OpenGLProfile, (int)profile);
|
||||
|
||||
if (mode.ColorFormat.BitsPerPixel > 0)
|
||||
{
|
||||
AddPixelAttrib(attributes, NSOpenGLPixelFormatAttribute.ColorSize, mode.ColorFormat.BitsPerPixel);
|
||||
}
|
||||
|
||||
if (mode.Depth > 0)
|
||||
{
|
||||
AddPixelAttrib(attributes, NSOpenGLPixelFormatAttribute.DepthSize, mode.Depth);
|
||||
}
|
||||
|
||||
if (mode.Stencil > 0)
|
||||
{
|
||||
AddPixelAttrib(attributes, NSOpenGLPixelFormatAttribute.StencilSize, mode.Stencil);
|
||||
}
|
||||
|
||||
if (mode.AccumulatorFormat.BitsPerPixel > 0)
|
||||
{
|
||||
AddPixelAttrib(attributes, NSOpenGLPixelFormatAttribute.AccumSize, mode.AccumulatorFormat.BitsPerPixel);
|
||||
}
|
||||
|
||||
if (mode.Samples > 1)
|
||||
{
|
||||
AddPixelAttrib(attributes, NSOpenGLPixelFormatAttribute.SampleBuffers, 1);
|
||||
AddPixelAttrib(attributes, NSOpenGLPixelFormatAttribute.Samples, mode.Samples);
|
||||
}
|
||||
|
||||
if (mode.Buffers > 1)
|
||||
{
|
||||
AddPixelAttrib(attributes, NSOpenGLPixelFormatAttribute.DoubleBuffer);
|
||||
}
|
||||
|
||||
// If at least a single accelerated pixel format is available,
|
||||
// then use that. If no accelerated formats are available, fall
|
||||
// back to software rendering.
|
||||
if (IsAccelerationSupported())
|
||||
{
|
||||
AddPixelAttrib(attributes, NSOpenGLPixelFormatAttribute.Accelerated);
|
||||
}
|
||||
|
||||
AddPixelAttrib(attributes, (NSOpenGLPixelFormatAttribute)0);
|
||||
|
||||
Debug.Unindent();
|
||||
|
||||
Debug.Write("Attribute array: ");
|
||||
for (int i = 0; i < attributes.Count; i++)
|
||||
{
|
||||
Debug.Write(attributes[i].ToString() + " ");
|
||||
}
|
||||
Debug.WriteLine("");
|
||||
|
||||
// Create pixel format
|
||||
var pixelFormat = Cocoa.SendIntPtr(Class.Get("NSOpenGLPixelFormat"), Selector.Alloc);
|
||||
|
||||
unsafe
|
||||
{
|
||||
fixed (NSOpenGLPixelFormatAttribute* ptr = attributes.ToArray())
|
||||
{
|
||||
pixelFormat = Cocoa.SendIntPtr(pixelFormat, Selector.Get("initWithAttributes:"), (IntPtr)ptr);
|
||||
}
|
||||
}
|
||||
|
||||
return pixelFormat;
|
||||
}
|
||||
|
||||
private bool IsAccelerationSupported()
|
||||
{
|
||||
IntPtr pf = IntPtr.Zero;
|
||||
int count = 0;
|
||||
Cgl.ChoosePixelFormat(new int[] { (int)Cgl.PixelFormatBool.Accelerated, 0 },
|
||||
ref pf, ref count);
|
||||
|
||||
if (pf != IntPtr.Zero)
|
||||
{
|
||||
Cgl.DestroyPixelFormat(pf);
|
||||
}
|
||||
|
||||
return pf != IntPtr.Zero;
|
||||
}
|
||||
|
||||
private GraphicsMode GetGraphicsMode(IntPtr context)
|
||||
{
|
||||
IntPtr cgl_context = Cocoa.SendIntPtr(context, Selector.Get("CGLContextObj"));
|
||||
IntPtr cgl_format = Cgl.GetPixelFormat(cgl_context);
|
||||
|
||||
int id = 0; // CGL does not support the concept of a pixel format id
|
||||
int color, depth, stencil, samples, accum;
|
||||
bool doublebuffer, stereo;
|
||||
Cgl.DescribePixelFormat(cgl_format, 0, Cgl.PixelFormatInt.ColorSize, out color);
|
||||
Cgl.DescribePixelFormat(cgl_format, 0, Cgl.PixelFormatInt.DepthSize, out depth);
|
||||
Cgl.DescribePixelFormat(cgl_format, 0, Cgl.PixelFormatInt.StencilSize, out stencil);
|
||||
Cgl.DescribePixelFormat(cgl_format, 0, Cgl.PixelFormatInt.Samples, out samples);
|
||||
Cgl.DescribePixelFormat(cgl_format, 0, Cgl.PixelFormatInt.AccumSize, out accum);
|
||||
Cgl.DescribePixelFormat(cgl_format, 0, Cgl.PixelFormatBool.Doublebuffer, out doublebuffer);
|
||||
Cgl.DescribePixelFormat(cgl_format, 0, Cgl.PixelFormatBool.Stereo, out stereo);
|
||||
|
||||
return new GraphicsMode((IntPtr)id, color, depth, stencil, samples, accum, doublebuffer ? 2 : 1, stereo);
|
||||
}
|
||||
|
||||
public override void SwapBuffers()
|
||||
{
|
||||
Cocoa.SendVoid(Handle.Handle, selFlushBuffer);
|
||||
}
|
||||
|
||||
public override void MakeCurrent(IWindowInfo window)
|
||||
{
|
||||
Cocoa.SendVoid(Handle.Handle, selMakeCurrentContext);
|
||||
}
|
||||
|
||||
public override bool IsCurrent
|
||||
{
|
||||
get
|
||||
{
|
||||
return Handle.Handle == CurrentContext;
|
||||
}
|
||||
}
|
||||
|
||||
public static IntPtr CurrentContext
|
||||
{
|
||||
get
|
||||
{
|
||||
return Cocoa.SendIntPtr(NSOpenGLContext, selCurrentContext);
|
||||
}
|
||||
}
|
||||
|
||||
private unsafe void SetContextValue (int val, NSOpenGLContextParameter par)
|
||||
{
|
||||
int* p = &val;
|
||||
Cocoa.SendVoid(Handle.Handle, Selector.Get("setValues:forParameter:"), (IntPtr)p, (int)par);
|
||||
}
|
||||
|
||||
private unsafe int GetContextValue (NSOpenGLContextParameter par)
|
||||
{
|
||||
int ret;
|
||||
int* p = &ret;
|
||||
Cocoa.SendVoid(Handle.Handle, Selector.Get("getValues:forParameter:"), (IntPtr)p, (int)par);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public override int SwapInterval
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetContextValue(NSOpenGLContextParameter.SwapInterval);
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value < 0)
|
||||
{
|
||||
// NSOpenGL does not offer EXT_swap_control_tear yet
|
||||
value = 1;
|
||||
}
|
||||
SetContextValue(value, NSOpenGLContextParameter.SwapInterval);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update(IWindowInfo window)
|
||||
{
|
||||
Cocoa.SendVoid(Handle.Handle, selUpdate);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (IsDisposed || Handle.Handle == IntPtr.Zero)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Print("Disposing of Cocoa context.");
|
||||
|
||||
if (!NSApplication.IsUIThread)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
using (var pool = new NSAutoreleasePool())
|
||||
{
|
||||
if (IsCurrent)
|
||||
{
|
||||
Cocoa.SendVoid(NSOpenGLContext, Selector.Get("clearCurrentContext"));
|
||||
}
|
||||
|
||||
Cocoa.SendVoid(Handle.Handle, Selector.Get("clearDrawable"));
|
||||
Cocoa.SendVoid(Handle.Handle, Selector.Get("release"));
|
||||
}
|
||||
|
||||
Handle = ContextHandle.Zero;
|
||||
|
||||
IsDisposed = true;
|
||||
}
|
||||
|
||||
public override IntPtr GetAddress(IntPtr function)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
// Add a leading underscore to the function name
|
||||
// As of OpenGL 4.4, all functions are < 64 bytes
|
||||
// in length. Double that just to be sure.
|
||||
const int max = 128;
|
||||
byte* fun = stackalloc byte[max];
|
||||
byte* ptr = fun;
|
||||
byte* cur = (byte*)function.ToPointer();
|
||||
int i = 0;
|
||||
|
||||
*ptr++ = (byte)'_';
|
||||
while (*cur != 0 && ++i < max)
|
||||
{
|
||||
*ptr++ = *cur++;
|
||||
}
|
||||
|
||||
if (i >= max - 1)
|
||||
{
|
||||
Debug.Print("Function {0} too long. Loading will fail.",
|
||||
Marshal.PtrToStringAnsi(function));
|
||||
}
|
||||
|
||||
IntPtr address = IntPtr.Zero;
|
||||
IntPtr symbol = IntPtr.Zero;
|
||||
if (opengl != IntPtr.Zero)
|
||||
{
|
||||
symbol = NS.LookupSymbolInImage(opengl, new IntPtr(fun),
|
||||
SymbolLookupFlags.Bind | SymbolLookupFlags.ReturnOnError);
|
||||
}
|
||||
if (symbol == IntPtr.Zero && opengles != IntPtr.Zero)
|
||||
{
|
||||
symbol = NS.LookupSymbolInImage(opengles, new IntPtr(fun),
|
||||
SymbolLookupFlags.Bind | SymbolLookupFlags.ReturnOnError);
|
||||
}
|
||||
if (symbol != IntPtr.Zero)
|
||||
{
|
||||
address = NS.AddressOfSymbol(symbol);
|
||||
}
|
||||
return address;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
113
GLWidget/OpenTK/Platform/MacOS/CocoaWindowInfo.cs
Normal file
113
GLWidget/OpenTK/Platform/MacOS/CocoaWindowInfo.cs
Normal file
|
@ -0,0 +1,113 @@
|
|||
//
|
||||
// CocoaWindowInfo.cs
|
||||
//
|
||||
// Author:
|
||||
// Olle Håkansson <ollhak@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2014 Olle Håkansson
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace OpenTK.Platform.MacOS
|
||||
{
|
||||
/// \internal
|
||||
/// <summary>
|
||||
/// Describes a Cocoa window.
|
||||
/// </summary>
|
||||
internal sealed class CocoaWindowInfo : IWindowInfo
|
||||
{
|
||||
private static readonly IntPtr selContentView = Selector.Get("contentView");
|
||||
|
||||
private bool disposed = false;
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new instance with the specified parameters.
|
||||
/// </summary>
|
||||
/// <remarks>This constructor assumes that the NSWindow's contentView is the NSView we want to attach to our context.</remarks>
|
||||
/// <param name="nsWindowRef">A valid NSWindow reference.</param>
|
||||
public CocoaWindowInfo(IntPtr nsWindowRef) : this(nsWindowRef, Cocoa.SendIntPtr(nsWindowRef, selContentView))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new instance with the specified parameters.
|
||||
/// </summary>
|
||||
/// <param name="nsWindowRef">A valid NSWindow reference.</param>
|
||||
/// <param name="nsViewRef">A valid NSView reference.</param>
|
||||
public CocoaWindowInfo(IntPtr nsWindowRef, IntPtr nsViewRef)
|
||||
{
|
||||
this.Handle = nsWindowRef;
|
||||
this.ViewHandle = nsViewRef;
|
||||
Cocoa.SendVoid(nsWindowRef, Selector.Retain);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the window reference for this instance.
|
||||
/// </summary>
|
||||
public IntPtr Handle { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the view reference for this instance.
|
||||
/// </summary>
|
||||
public IntPtr ViewHandle { get; }
|
||||
|
||||
/// <summary>Returns a System.String that represents the current window.</summary>
|
||||
/// <returns>A System.String that represents the current window.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("MacOS.CocoaWindowInfo: NSWindow {0}, NSView {1}", Handle, ViewHandle);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
if (disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
Cocoa.SendVoid(Handle, Selector.Release);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Print("CocoaWindowInfo:{0} leaked, did you forget to call Dispose()?", Handle);
|
||||
}
|
||||
|
||||
disposed = true;
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
~CocoaWindowInfo()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
34
GLWidget/OpenTK/Platform/MacOS/CoreVideo.cs
Normal file
34
GLWidget/OpenTK/Platform/MacOS/CoreVideo.cs
Normal file
|
@ -0,0 +1,34 @@
|
|||
// See License.txt file for copyright details
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OpenTK.Platform.MacOS
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct CVTime
|
||||
{
|
||||
public Int64 timeValue;
|
||||
public Int32 timeScale;
|
||||
public Int32 flags;
|
||||
}
|
||||
|
||||
internal class CV
|
||||
{
|
||||
private const string LibPath = "/System/Library/Frameworks/CoreVideo.framework/Versions/Current/CoreVideo";
|
||||
|
||||
internal enum TimeFlags : Int32
|
||||
{
|
||||
TimeIsIndefinite = 1 << 0
|
||||
}
|
||||
|
||||
[DllImport(LibPath, EntryPoint = "CVDisplayLinkCreateWithCGDisplay")]
|
||||
public extern static IntPtr DisplayLinkCreateWithCGDisplay(IntPtr currentDisplay, out IntPtr displayLink);
|
||||
|
||||
[DllImport(LibPath, EntryPoint = "CVDisplayLinkGetNominalOutputVideoRefreshPeriod")]
|
||||
public extern static CVTime DisplayLinkGetNominalOutputVideoRefreshPeriod(IntPtr displayLink);
|
||||
|
||||
[DllImport(LibPath, EntryPoint = "CVDisplayLinkRelease")]
|
||||
public extern static void DisplayLinkRelease(IntPtr displayLink);
|
||||
}
|
||||
}
|
117
GLWidget/OpenTK/Platform/MacOS/MacOSException.cs
Normal file
117
GLWidget/OpenTK/Platform/MacOS/MacOSException.cs
Normal file
|
@ -0,0 +1,117 @@
|
|||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2010 the Open Toolkit library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
// Created by Erik Ylvisaker on 3/17/08.
|
||||
|
||||
using System;
|
||||
|
||||
namespace OpenTK.Platform.MacOS
|
||||
{
|
||||
internal class MacOSException : Exception
|
||||
{
|
||||
public MacOSException()
|
||||
{}
|
||||
public MacOSException(OSStatus errorCode)
|
||||
: base("Error Code " + ((int)errorCode).ToString() + ": " + errorCode.ToString())
|
||||
{
|
||||
this.ErrorCode = errorCode;
|
||||
}
|
||||
public MacOSException(OSStatus errorCode, string message)
|
||||
: base(message)
|
||||
{
|
||||
this.ErrorCode = errorCode;
|
||||
}
|
||||
internal MacOSException(int errorCode, string message)
|
||||
: base(message)
|
||||
{
|
||||
this.ErrorCode = (OSStatus)errorCode;
|
||||
}
|
||||
|
||||
public OSStatus ErrorCode { get; }
|
||||
}
|
||||
|
||||
internal enum OSStatus
|
||||
{
|
||||
NoError = 0,
|
||||
|
||||
ParameterError = -50, /*error in user parameter list*/
|
||||
NoHardwareError = -200, /*Sound Manager Error Returns*/
|
||||
NotEnoughHardwareError = -201, /*Sound Manager Error Returns*/
|
||||
UserCanceledError = -128,
|
||||
QueueError = -1, /*queue element not found during deletion*/
|
||||
VTypErr = -2, /*invalid queue element*/
|
||||
CorErr = -3, /*core routine number out of range*/
|
||||
UnimpErr = -4, /*unimplemented core routine*/
|
||||
SlpTypeErr = -5, /*invalid queue element*/
|
||||
SeNoDB = -8, /*no debugger installed to handle debugger command*/
|
||||
ControlErr = -17, /*I/O System Errors*/
|
||||
StatusErr = -18, /*I/O System Errors*/
|
||||
ReadErr = -19, /*I/O System Errors*/
|
||||
WritErr = -20, /*I/O System Errors*/
|
||||
BadUnitErr = -21, /*I/O System Errors*/
|
||||
UnitEmptyErr = -22, /*I/O System Errors*/
|
||||
OpenErr = -23, /*I/O System Errors*/
|
||||
ClosErr = -24, /*I/O System Errors*/
|
||||
DRemovErr = -25, /*tried to remove an open driver*/
|
||||
DInstErr = -26, /*DrvrInstall couldn't find driver in resources*/
|
||||
|
||||
// Window Manager result codes.
|
||||
InvalidWindowPtr = -5600,
|
||||
UnsupportedWindowAttributesForClass = -5601,
|
||||
WindowDoesNotHaveProxy = -5602,
|
||||
WindowPropertyNotFound = -5604,
|
||||
UnrecognizedWindowClass = -5605,
|
||||
CorruptWindowDescription = -5606,
|
||||
UserWantsToDragWindow = -5607,
|
||||
WindowsAlreadyInitialized = -5608,
|
||||
FloatingWindowsNotInitialized = -5609,
|
||||
WindowNotFound = -5610,
|
||||
WindowDoesNotFitOnscreen = -5611,
|
||||
WindowAttributeImmutable = -5612,
|
||||
WindowAttributesConflict = -5613,
|
||||
WindowManagerInternalError = -5614,
|
||||
WindowWrongState = -5615,
|
||||
WindowGroupInvalid = -5616,
|
||||
WindowAppModalStateAlreadyExists = -5617,
|
||||
WindowNoAppModalState = -5618,
|
||||
WindowDoesntSupportFocus = -30583,
|
||||
WindowRegionCodeInvalid = -30593,
|
||||
|
||||
// Event Manager result codes
|
||||
EventAlreadyPosted = -9860,
|
||||
EventTargetBusy = -9861,
|
||||
EventDeferAccessibilityEvent = -9865,
|
||||
EventInternalError = -9868,
|
||||
EventParameterNotFound = -9870,
|
||||
EventNotHandled = -9874,
|
||||
EventLoopTimedOut = -9875,
|
||||
EventLoopQuit = -9876,
|
||||
EventNotInQueue = -9877,
|
||||
HotKeyExists = -9878,
|
||||
EventPassToNextTarget = -9880
|
||||
|
||||
}
|
||||
|
||||
}
|
74
GLWidget/OpenTK/Platform/MacOS/MacOSFactory.cs
Normal file
74
GLWidget/OpenTK/Platform/MacOS/MacOSFactory.cs
Normal file
|
@ -0,0 +1,74 @@
|
|||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2009 the Open Toolkit library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
namespace OpenTK.Platform.MacOS
|
||||
{
|
||||
using Graphics;
|
||||
|
||||
internal class MacOSFactory : PlatformFactoryBase
|
||||
{
|
||||
// Todo: we can query the exact amount via
|
||||
// CGEventSourceGetPixelsPerLine. This is
|
||||
// approximately 0.1f
|
||||
internal const float ScrollFactor = 0.1f;
|
||||
internal static bool ExclusiveFullscreen = false;
|
||||
|
||||
public MacOSFactory()
|
||||
{
|
||||
NSApplication.Initialize();
|
||||
}
|
||||
|
||||
public override IDisplayDeviceDriver CreateDisplayDeviceDriver()
|
||||
{
|
||||
return new QuartzDisplayDeviceDriver();
|
||||
}
|
||||
|
||||
public override IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
|
||||
{
|
||||
return new CocoaContext(mode, window, shareContext, major, minor);
|
||||
}
|
||||
|
||||
public override IGraphicsContext CreateGLContext(ContextHandle handle, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
|
||||
{
|
||||
return new CocoaContext(handle, window, shareContext, major, minor);
|
||||
}
|
||||
|
||||
public override GraphicsContext.GetCurrentContextDelegate CreateGetCurrentGraphicsContext()
|
||||
{
|
||||
return (GraphicsContext.GetCurrentContextDelegate)delegate
|
||||
{
|
||||
return new ContextHandle(CocoaContext.CurrentContext);
|
||||
};
|
||||
}
|
||||
|
||||
protected override void Dispose(bool manual)
|
||||
{
|
||||
if (!IsDisposed)
|
||||
{
|
||||
base.Dispose(manual);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
170
GLWidget/OpenTK/Platform/MacOS/NS.cs
Normal file
170
GLWidget/OpenTK/Platform/MacOS/NS.cs
Normal file
|
@ -0,0 +1,170 @@
|
|||
//
|
||||
// NS.cs
|
||||
//
|
||||
// Author:
|
||||
// Stefanos A. <stapostol@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2006-2013 Stefanos Apostolopoulos
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OpenTK.Platform.MacOS
|
||||
{
|
||||
[Flags]
|
||||
internal enum AddImageFlags
|
||||
{
|
||||
ReturnOnError = 1,
|
||||
WithSearching = 2,
|
||||
ReturnOnlyIfLoaded = 4
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum SymbolLookupFlags
|
||||
{
|
||||
Bind = 0,
|
||||
BindNow = 1,
|
||||
BindFully = 2,
|
||||
ReturnOnError = 4
|
||||
}
|
||||
|
||||
internal class NS
|
||||
{
|
||||
private const string Library = "libdl.dylib";
|
||||
|
||||
[DllImport(Library, EntryPoint = "NSAddImage")]
|
||||
internal static extern IntPtr AddImage(string s, AddImageFlags flags);
|
||||
[DllImport(Library, EntryPoint = "NSAddressOfSymbol")]
|
||||
internal static extern IntPtr AddressOfSymbol(IntPtr symbol);
|
||||
[DllImport(Library, EntryPoint = "NSIsSymbolNameDefined")]
|
||||
internal static extern bool IsSymbolNameDefined(string s);
|
||||
[DllImport(Library, EntryPoint = "NSIsSymbolNameDefined")]
|
||||
internal static extern bool IsSymbolNameDefined(IntPtr s);
|
||||
[DllImport(Library, EntryPoint = "NSLookupAndBindSymbol")]
|
||||
internal static extern IntPtr LookupAndBindSymbol(string s);
|
||||
[DllImport(Library, EntryPoint = "NSLookupAndBindSymbol")]
|
||||
internal static extern IntPtr LookupAndBindSymbol(IntPtr s);
|
||||
[DllImport(Library, EntryPoint = "NSLookupSymbolInImage")]
|
||||
internal static extern IntPtr LookupSymbolInImage(IntPtr image, IntPtr symbolName, SymbolLookupFlags options);
|
||||
|
||||
// Unfortunately, these are slower even if they are more
|
||||
// portable and simpler to use.
|
||||
[DllImport(Library)]
|
||||
internal static extern IntPtr dlopen(String fileName, int flags);
|
||||
[DllImport(Library)]
|
||||
internal static extern int dlclose(IntPtr handle);
|
||||
[DllImport (Library)]
|
||||
internal static extern IntPtr dlsym (IntPtr handle, string symbol);
|
||||
[DllImport (Library)]
|
||||
internal static extern IntPtr dlsym (IntPtr handle, IntPtr symbol);
|
||||
|
||||
public static IntPtr GetAddress(string function)
|
||||
{
|
||||
// Instead of allocating and combining strings in managed memory
|
||||
// we do that directly in unmanaged memory. This way, we avoid
|
||||
// 2 string allocations every time this function is called.
|
||||
|
||||
// must add a '_' prefix and null-terminate the function name,
|
||||
// hence we allocate +2 bytes
|
||||
IntPtr ptr = Marshal.AllocHGlobal(function.Length + 2);
|
||||
try
|
||||
{
|
||||
Marshal.WriteByte(ptr, (byte)'_');
|
||||
for (int i = 0; i < function.Length; i++)
|
||||
{
|
||||
Marshal.WriteByte(ptr, i + 1, (byte)function[i]);
|
||||
}
|
||||
Marshal.WriteByte(ptr, function.Length + 1, 0); // null-terminate
|
||||
|
||||
IntPtr symbol = GetAddressInternal(ptr);
|
||||
return symbol;
|
||||
}
|
||||
finally
|
||||
{
|
||||
Marshal.FreeHGlobal(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
public static IntPtr GetAddress(IntPtr function)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
const int max = 64;
|
||||
byte* symbol = stackalloc byte[max];
|
||||
byte* ptr = symbol;
|
||||
byte* cur = (byte*)function.ToPointer();
|
||||
int i = 0;
|
||||
|
||||
*ptr++ = (byte)'_';
|
||||
while (*cur != 0 && ++i < max)
|
||||
{
|
||||
*ptr++ = *cur++;
|
||||
}
|
||||
|
||||
if (i >= max - 1)
|
||||
{
|
||||
throw new NotSupportedException(String.Format(
|
||||
"Function {0} is too long. Please report a bug at https://github.com/opentk/issues/issues",
|
||||
Marshal.PtrToStringAnsi(function)));
|
||||
}
|
||||
|
||||
return GetAddressInternal(new IntPtr(symbol));
|
||||
}
|
||||
}
|
||||
|
||||
private static IntPtr GetAddressInternal(IntPtr function)
|
||||
{
|
||||
IntPtr symbol = IntPtr.Zero;
|
||||
if (IsSymbolNameDefined(function))
|
||||
{
|
||||
symbol = LookupAndBindSymbol(function);
|
||||
if (symbol != IntPtr.Zero)
|
||||
{
|
||||
symbol = AddressOfSymbol(symbol);
|
||||
}
|
||||
}
|
||||
return symbol;
|
||||
}
|
||||
|
||||
public static IntPtr GetSymbol(IntPtr handle, string symbol)
|
||||
{
|
||||
return dlsym(handle, symbol);
|
||||
}
|
||||
|
||||
public static IntPtr GetSymbol(IntPtr handle, IntPtr symbol)
|
||||
{
|
||||
return dlsym(handle, symbol);
|
||||
}
|
||||
|
||||
public static IntPtr LoadLibrary(string fileName)
|
||||
{
|
||||
const int RTLD_NOW = 2;
|
||||
return dlopen(fileName, RTLD_NOW);
|
||||
}
|
||||
|
||||
public static void FreeLibrary(IntPtr handle)
|
||||
{
|
||||
dlclose(handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
244
GLWidget/OpenTK/Platform/MacOS/Quartz/CoreFoundation.cs
Normal file
244
GLWidget/OpenTK/Platform/MacOS/Quartz/CoreFoundation.cs
Normal file
|
@ -0,0 +1,244 @@
|
|||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2010 the Open Toolkit library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenTK.Platform.MacOS.Carbon
|
||||
{
|
||||
using CFAllocatorRef = IntPtr;
|
||||
using CFIndex = System.IntPtr;
|
||||
using CFRunLoop = System.IntPtr;
|
||||
using CFRunLoopRef = IntPtr;
|
||||
using CFRunLoopSourceRef = IntPtr;
|
||||
using CFStringRef = System.IntPtr;
|
||||
using CFTypeRef = System.IntPtr;
|
||||
using CFMachPortRef = IntPtr;
|
||||
|
||||
internal struct CFArray
|
||||
{
|
||||
public IntPtr Ref { get; set; }
|
||||
|
||||
public CFArray(IntPtr reference)
|
||||
{
|
||||
Ref = reference;
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return CF.CFArrayGetCount(Ref); }
|
||||
}
|
||||
public IntPtr this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (index >= Count || index < 0)
|
||||
{
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
|
||||
return CF.CFArrayGetValueAtIndex(Ref, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal struct CFDictionary
|
||||
{
|
||||
public CFDictionary(IntPtr reference)
|
||||
{
|
||||
Ref = reference;
|
||||
}
|
||||
|
||||
public IntPtr Ref { get; set; }
|
||||
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
return CF.CFDictionaryGetCount(Ref);
|
||||
}
|
||||
}
|
||||
|
||||
public double GetNumberValue(string key)
|
||||
{
|
||||
double retval;
|
||||
IntPtr cfnum = CF.CFDictionaryGetValue(Ref,
|
||||
CF.CFSTR(key));
|
||||
|
||||
CF.CFNumberGetValue(cfnum, CF.CFNumberType.kCFNumberDoubleType, out retval);
|
||||
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
internal class CF
|
||||
{
|
||||
private const string appServices = "/System/Library/Frameworks/ApplicationServices.framework/Versions/Current/ApplicationServices";
|
||||
|
||||
[DllImport(appServices)]
|
||||
internal static extern int CFArrayGetCount(IntPtr theArray);
|
||||
|
||||
[DllImport(appServices)]
|
||||
internal static extern IntPtr CFArrayGetValueAtIndex(IntPtr theArray, int idx);
|
||||
|
||||
[DllImport(appServices)]
|
||||
internal static extern int CFDictionaryGetCount(IntPtr theDictionary);
|
||||
|
||||
[DllImport(appServices)]
|
||||
internal static extern IntPtr CFDictionaryGetValue(IntPtr theDictionary, IntPtr theKey);
|
||||
|
||||
[DllImport(appServices)]
|
||||
internal static extern IntPtr CFGetTypeID(IntPtr v);
|
||||
|
||||
[DllImport(appServices)]
|
||||
internal static extern IntPtr CFRetain(CFTypeRef cf);
|
||||
|
||||
[DllImport(appServices)]
|
||||
internal static extern void CFRelease(CFTypeRef cf);
|
||||
|
||||
// this mirrors the definition in CFString.h.
|
||||
// I don't know why, but __CFStringMakeConstantString is marked as "private and should not be used directly"
|
||||
// even though the CFSTR macro just calls it.
|
||||
[DllImport(appServices)]
|
||||
private static extern IntPtr __CFStringMakeConstantString(string cStr);
|
||||
internal static IntPtr CFSTR(string cStr)
|
||||
{
|
||||
return __CFStringMakeConstantString(cStr);
|
||||
}
|
||||
|
||||
[DllImport(appServices)]
|
||||
internal static extern Boolean CFStringGetCString(
|
||||
CFStringRef theString,
|
||||
byte[] buffer,
|
||||
CFIndex bufferSize,
|
||||
CFStringEncoding encoding
|
||||
);
|
||||
|
||||
internal static string CFStringGetCString(IntPtr cfstr)
|
||||
{
|
||||
CFIndex length = CFStringGetLength(cfstr);
|
||||
if (length != IntPtr.Zero)
|
||||
{
|
||||
byte[] utf8_chars = new byte[length.ToInt32() + 1];
|
||||
if (CFStringGetCString(cfstr, utf8_chars, new IntPtr(utf8_chars.Length), CFStringEncoding.UTF8))
|
||||
{
|
||||
return Encoding.UTF8.GetString(utf8_chars);
|
||||
}
|
||||
}
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
[DllImport(appServices)]
|
||||
internal static extern CFIndex CFStringGetLength(
|
||||
CFStringRef theString
|
||||
);
|
||||
|
||||
[DllImport(appServices)]
|
||||
internal static extern bool CFNumberGetValue (IntPtr number, CFNumberType theType, out int valuePtr);
|
||||
[DllImport(appServices)]
|
||||
internal static extern bool CFNumberGetValue (IntPtr number, CFNumberType theType, out long valuePtr);
|
||||
[DllImport(appServices)]
|
||||
internal static extern bool CFNumberGetValue(IntPtr number, CFNumberType theType, out double valuePtr);
|
||||
|
||||
internal enum CFNumberType
|
||||
{
|
||||
kCFNumberSInt8Type = 1,
|
||||
kCFNumberSInt16Type = 2,
|
||||
kCFNumberSInt32Type = 3,
|
||||
kCFNumberSInt64Type = 4,
|
||||
kCFNumberFloat32Type = 5,
|
||||
kCFNumberFloat64Type = 6,
|
||||
kCFNumberCharType = 7,
|
||||
kCFNumberShortType = 8,
|
||||
kCFNumberIntType = 9,
|
||||
kCFNumberLongType = 10,
|
||||
kCFNumberLongLongType = 11,
|
||||
kCFNumberFloatType = 12,
|
||||
kCFNumberDoubleType = 13,
|
||||
kCFNumberCFIndexType = 14,
|
||||
kCFNumberNSIntegerType = 15,
|
||||
kCFNumberCGFloatType = 16,
|
||||
kCFNumberMaxType = 16
|
||||
};
|
||||
|
||||
public enum CFRunLoopExitReason
|
||||
{
|
||||
Finished = 1,
|
||||
Stopped = 2,
|
||||
TimedOut = 3,
|
||||
HandledSource = 4
|
||||
}
|
||||
|
||||
public enum CFStringEncoding
|
||||
{
|
||||
MacRoman = 0,
|
||||
WindowsLatin1 = 0x0500,
|
||||
ISOLatin1 = 0x0201,
|
||||
NextStepLatin = 0x0B01,
|
||||
ASCII = 0x0600,
|
||||
Unicode = 0x0100,
|
||||
UTF8 = 0x08000100,
|
||||
NonLossyASCII = 0x0BFF,
|
||||
|
||||
UTF16 = 0x0100,
|
||||
UTF16BE = 0x10000100,
|
||||
UTF16LE = 0x14000100,
|
||||
UTF32 = 0x0c000100,
|
||||
UTF32BE = 0x18000100,
|
||||
UTF32LE = 0x1c000100
|
||||
}
|
||||
|
||||
public static readonly IntPtr RunLoopModeDefault = CF.CFSTR("kCFRunLoopDefaultMode");
|
||||
|
||||
[DllImport(appServices)]
|
||||
internal static extern CFRunLoop CFRunLoopGetCurrent();
|
||||
|
||||
[DllImport(appServices)]
|
||||
internal static extern CFRunLoop CFRunLoopGetMain();
|
||||
|
||||
[DllImport(appServices)]
|
||||
internal static extern CFRunLoopExitReason CFRunLoopRunInMode(
|
||||
IntPtr cfstrMode, double interval, bool returnAfterSourceHandled);
|
||||
|
||||
[DllImport(appServices, EntryPoint = "CFMachPortCreateRunLoopSource")]
|
||||
internal static extern CFRunLoopSourceRef MachPortCreateRunLoopSource(
|
||||
CFAllocatorRef allocator,
|
||||
CFMachPortRef port,
|
||||
CFIndex order);
|
||||
|
||||
[DllImport(appServices, EntryPoint = "CFRunLoopAddSource")]
|
||||
internal static extern void RunLoopAddSource(
|
||||
CFRunLoopRef rl,
|
||||
CFRunLoopSourceRef source,
|
||||
CFStringRef mode);
|
||||
|
||||
[DllImport(appServices, EntryPoint = "CFRunLoopRemoveSource")]
|
||||
internal static extern void RunLoopRemoveSource(
|
||||
CFRunLoopRef rl,
|
||||
CFRunLoopSourceRef source,
|
||||
CFStringRef mode);
|
||||
}
|
||||
}
|
132
GLWidget/OpenTK/Platform/MacOS/Quartz/DisplayServices.cs
Normal file
132
GLWidget/OpenTK/Platform/MacOS/Quartz/DisplayServices.cs
Normal file
|
@ -0,0 +1,132 @@
|
|||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2010 the Open Toolkit library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OpenTK.Platform.MacOS
|
||||
{
|
||||
using CGDirectDisplayID = System.IntPtr;
|
||||
|
||||
// Quartz Display services used here are available in MacOS X 10.3 and later.
|
||||
|
||||
internal enum CGDisplayErr
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
internal enum CGError
|
||||
{
|
||||
Success = 0,
|
||||
Failure = 1000,
|
||||
IllegalArgument = 1001,
|
||||
InvalidConnection = 1002,
|
||||
InvalidContext = 1003,
|
||||
CannotComplete = 1004,
|
||||
NotImplemented = 1006,
|
||||
RangeCheck = 1007,
|
||||
TypeCheck = 1008,
|
||||
InvalidOperation = 1010,
|
||||
NoneAvailable = 1011,
|
||||
}
|
||||
|
||||
internal partial class CG
|
||||
{
|
||||
private const string lib = "/System/Library/Frameworks/ApplicationServices.framework/Versions/Current/ApplicationServices";
|
||||
|
||||
// CGPoint -> NSPoint
|
||||
// CGSize -> NSSize
|
||||
// CGRect -> NSRect
|
||||
|
||||
[DllImport(lib, EntryPoint="CGGetActiveDisplayList")]
|
||||
internal unsafe static extern CGDisplayErr GetActiveDisplayList(int maxDisplays, IntPtr* activeDspys, out int dspyCnt);
|
||||
|
||||
[DllImport(lib, EntryPoint="CGMainDisplayID")]
|
||||
internal static extern IntPtr MainDisplayID();
|
||||
|
||||
// Note: sizeof(HIRect) == 16, which is larger than 8 bytes.
|
||||
// The x86 and x64 Mac ABIs pass such structs as pointers in the
|
||||
// first parameter slot. This is normally handled automatically
|
||||
// by gcc/clang, but here we have to do it ourselves.
|
||||
// See "Listing 4" on https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/LowLevelABI/130-IA-32_Function_Calling_Conventions/IA32.html#//apple_ref/doc/uid/TP40002492-SW3
|
||||
internal unsafe static NSRect DisplayBounds(IntPtr display)
|
||||
{
|
||||
NSRect rect;
|
||||
DisplayBounds(out rect, display);
|
||||
return rect;
|
||||
}
|
||||
|
||||
[DllImport(lib, EntryPoint = "CGDisplayBounds")]
|
||||
private unsafe static extern void DisplayBounds(out NSRect rect, IntPtr display);
|
||||
|
||||
[DllImport(lib, EntryPoint="CGDisplayPixelsWide")]
|
||||
internal static extern int DisplayPixelsWide(IntPtr display);
|
||||
|
||||
[DllImport(lib, EntryPoint="CGDisplayPixelsHigh")]
|
||||
internal static extern int DisplayPixelsHigh(IntPtr display);
|
||||
|
||||
[DllImport(lib, EntryPoint="CGDisplayCurrentMode")]
|
||||
internal static extern IntPtr DisplayCurrentMode(IntPtr display);
|
||||
|
||||
[DllImport(lib, EntryPoint="CGDisplayCapture")]
|
||||
internal static extern CGDisplayErr DisplayCapture(IntPtr display);
|
||||
|
||||
[DllImport(lib, EntryPoint="CGCaptureAllDisplays")]
|
||||
internal static extern CGDisplayErr CaptureAllDisplays();
|
||||
|
||||
[DllImport(lib, EntryPoint="CGShieldingWindowLevel")]
|
||||
internal static extern uint ShieldingWindowLevel();
|
||||
|
||||
[DllImport(lib, EntryPoint="CGDisplayRelease")]
|
||||
internal static extern CGDisplayErr DisplayRelease(IntPtr display);
|
||||
|
||||
[DllImport(lib, EntryPoint="CGReleaseAllDisplays")]
|
||||
internal static extern CGDisplayErr DisplayReleaseAll();
|
||||
|
||||
[DllImport(lib, EntryPoint = "CGDisplayAvailableModes")]
|
||||
internal static extern IntPtr DisplayAvailableModes(IntPtr display);
|
||||
|
||||
[DllImport(lib, EntryPoint = "CGDisplaySwitchToMode")]
|
||||
internal static extern IntPtr DisplaySwitchToMode(IntPtr display, IntPtr displayMode);
|
||||
|
||||
[DllImport(lib, EntryPoint = "CGWarpMouseCursorPosition")]
|
||||
internal static extern CGError WarpMouseCursorPosition(NSPoint newCursorPosition);
|
||||
|
||||
[DllImport(lib, EntryPoint = "CGCursorIsVisible")]
|
||||
internal static extern bool CursorIsVisible();
|
||||
|
||||
[DllImport(lib, EntryPoint = "CGDisplayShowCursor")]
|
||||
internal static extern CGError DisplayShowCursor(CGDirectDisplayID display);
|
||||
|
||||
[DllImport(lib, EntryPoint = "CGDisplayHideCursor")]
|
||||
internal static extern CGError DisplayHideCursor(CGDirectDisplayID display);
|
||||
|
||||
[DllImport(lib, EntryPoint = "CGAssociateMouseAndMouseCursorPosition")]
|
||||
internal static extern CGError AssociateMouseAndMouseCursorPosition(bool connected);
|
||||
|
||||
[DllImport(lib, EntryPoint="CGSetLocalEventsSuppressionInterval")]
|
||||
internal static extern CGError SetLocalEventsSuppressionInterval(double seconds);
|
||||
}
|
||||
}
|
221
GLWidget/OpenTK/Platform/MacOS/Quartz/EventServices.cs
Normal file
221
GLWidget/OpenTK/Platform/MacOS/Quartz/EventServices.cs
Normal file
|
@ -0,0 +1,221 @@
|
|||
//
|
||||
// EventServices.cs
|
||||
//
|
||||
// Author:
|
||||
// Stefanos A. <stapostol@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2006-2014 Stefanos Apostolopoulos
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OpenTK.Platform.MacOS
|
||||
{
|
||||
using CGEventTapProxy = IntPtr;
|
||||
using CGEventRef = IntPtr;
|
||||
using CFMachPortRef = IntPtr;
|
||||
|
||||
internal partial class CG
|
||||
{
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate CGEventRef EventTapCallBack(
|
||||
CGEventTapProxy proxy,
|
||||
CGEventType type,
|
||||
CGEventRef @event,
|
||||
IntPtr refcon);
|
||||
|
||||
[DllImport(lib, EntryPoint = "CGEventTapCreate")]
|
||||
public static extern CFMachPortRef EventTapCreate(
|
||||
CGEventTapLocation tap,
|
||||
CGEventTapPlacement place,
|
||||
CGEventTapOptions options,
|
||||
CGEventMask eventsOfInterest,
|
||||
[MarshalAs(UnmanagedType.FunctionPtr)]
|
||||
EventTapCallBack callback,
|
||||
IntPtr refcon);
|
||||
|
||||
[DllImport(lib, EntryPoint = "CGEventGetDoubleValueField")]
|
||||
internal static extern double EventGetDoubleValueField(
|
||||
CGEventRef @event,
|
||||
CGEventField field);
|
||||
|
||||
[DllImport(lib, EntryPoint = "CGEventGetIntegerValueField")]
|
||||
internal static extern int EventGetIntegerValueField(
|
||||
CGEventRef @event,
|
||||
CGEventField field);
|
||||
|
||||
[DllImport(lib, EntryPoint = "CGEventGetLocation")]
|
||||
internal static extern NSPointF EventGetLocationF(CGEventRef @event);
|
||||
[DllImport(lib, EntryPoint = "CGEventGetLocation")]
|
||||
internal static extern NSPointD EventGetLocationD(CGEventRef @event);
|
||||
|
||||
internal static NSPoint EventGetLocation(CGEventRef @event)
|
||||
{
|
||||
NSPoint r = new NSPoint();
|
||||
|
||||
unsafe {
|
||||
if (IntPtr.Size == 4)
|
||||
{
|
||||
NSPointF pf = EventGetLocationF(@event);
|
||||
r.X.Value = *(IntPtr *)&pf.X;
|
||||
r.Y.Value = *(IntPtr *)&pf.Y;
|
||||
}
|
||||
else
|
||||
{
|
||||
NSPointD pd = EventGetLocationD(@event);
|
||||
r.X.Value = *(IntPtr *)&pd.X;
|
||||
r.Y.Value = *(IntPtr *)&pd.Y;
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal enum CGEventTapLocation
|
||||
{
|
||||
HIDEventTap = 0,
|
||||
SessionEventTap,
|
||||
AnnotatedSessionEventTap
|
||||
}
|
||||
|
||||
internal enum CGEventTapPlacement
|
||||
{
|
||||
HeadInsert = 0,
|
||||
TailAppend
|
||||
}
|
||||
|
||||
internal enum CGEventTapOptions
|
||||
{
|
||||
Default = 0x00000000,
|
||||
ListenOnly = 0x00000001
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum CGEventMask : long
|
||||
{
|
||||
LeftMouseDown = 1 << CGEventType.LeftMouseDown,
|
||||
LeftMouseUp = 1 << CGEventType.LeftMouseUp,
|
||||
RightMouseDown = 1 << CGEventType.RightMouseDown,
|
||||
RightMouseUp = 1 << CGEventType.RightMouseUp,
|
||||
MouseMoved = 1 << CGEventType.MouseMoved,
|
||||
LeftMouseDragged = 1 << CGEventType.LeftMouseDown,
|
||||
RightMouseDragged = 1 << CGEventType.RightMouseDown,
|
||||
KeyDown = 1 << CGEventType.KeyDown,
|
||||
KeyUp = 1 << CGEventType.KeyUp,
|
||||
FlagsChanged = 1 << CGEventType.FlagsChanged,
|
||||
ScrollWheel = 1 << CGEventType.ScrollWheel,
|
||||
TabletPointer = 1 << CGEventType.TabletPointer,
|
||||
TabletProximity = 1 << CGEventType.TabletProximity,
|
||||
OtherMouseDown = 1 << CGEventType.OtherMouseDown,
|
||||
OtherMouseUp = 1 << CGEventType.OtherMouseUp,
|
||||
OtherMouseDragged = 1 << CGEventType.OtherMouseDragged,
|
||||
All = -1,
|
||||
AllMouse =
|
||||
LeftMouseDown | LeftMouseUp | LeftMouseDragged |
|
||||
RightMouseDown | RightMouseUp | RightMouseDragged |
|
||||
OtherMouseDown | OtherMouseUp | OtherMouseDragged |
|
||||
ScrollWheel | MouseMoved
|
||||
}
|
||||
|
||||
internal enum CGEventType
|
||||
{
|
||||
Null = 0,
|
||||
LeftMouseDown = 1,
|
||||
LeftMouseUp = 2,
|
||||
RightMouseDown = 3,
|
||||
RightMouseUp = 4,
|
||||
MouseMoved = 5,
|
||||
LeftMouseDragged = 6,
|
||||
RightMouseDragged = 7,
|
||||
KeyDown = 10,
|
||||
KeyUp = 11,
|
||||
FlagsChanged = 12,
|
||||
ScrollWheel = 22,
|
||||
TabletPointer = 23,
|
||||
TabletProximity = 24,
|
||||
OtherMouseDown = 25,
|
||||
OtherMouseUp = 26,
|
||||
OtherMouseDragged = 27,
|
||||
TapDisabledByTimeout = -2,
|
||||
TapDisabledByUserInput = -1
|
||||
}
|
||||
|
||||
internal enum CGEventField
|
||||
{
|
||||
MouseEventNumber = 0,
|
||||
MouseEventClickState = 1,
|
||||
MouseEventPressure = 2,
|
||||
MouseEventButtonNumber = 3,
|
||||
MouseEventDeltaX = 4,
|
||||
MouseEventDeltaY = 5,
|
||||
MouseEventInstantMouser = 6,
|
||||
MouseEventSubtype = 7,
|
||||
KeyboardEventAutorepeat = 8,
|
||||
KeyboardEventKeycode = 9,
|
||||
KeyboardEventKeyboardType = 10,
|
||||
ScrollWheelEventDeltaAxis1 = 11,
|
||||
ScrollWheelEventDeltaAxis2 = 12,
|
||||
ScrollWheelEventDeltaAxis3 = 13,
|
||||
ScrollWheelEventFixedPtDeltaAxis1 = 93,
|
||||
ScrollWheelEventFixedPtDeltaAxis2 = 94,
|
||||
ScrollWheelEventFixedPtDeltaAxis3 = 95,
|
||||
ScrollWheelEventPointDeltaAxis1 = 96,
|
||||
ScrollWheelEventPointDeltaAxis2 = 97,
|
||||
ScrollWheelEventPointDeltaAxis3 = 98,
|
||||
ScrollWheelEventInstantMouser = 14,
|
||||
TabletEventPointX = 15,
|
||||
TabletEventPointY = 16,
|
||||
TabletEventPointZ = 17,
|
||||
TabletEventPointButtons = 18,
|
||||
TabletEventPointPressure = 19,
|
||||
TabletEventTiltX = 20,
|
||||
TabletEventTiltY = 21,
|
||||
TabletEventRotation = 22,
|
||||
TabletEventTangentialPressure = 23,
|
||||
TabletEventDeviceID = 24,
|
||||
TabletEventVendor1 = 25,
|
||||
TabletEventVendor2 = 26,
|
||||
TabletEventVendor3 = 27,
|
||||
TabletProximityEventVendorID = 28,
|
||||
TabletProximityEventTabletID = 29,
|
||||
TabletProximityEventPointerID = 30,
|
||||
TabletProximityEventDeviceID = 31,
|
||||
TabletProximityEventSystemTabletID = 32,
|
||||
TabletProximityEventVendorPointerType = 33,
|
||||
TabletProximityEventVendorPointerSerialNumber = 34,
|
||||
TabletProximityEventVendorUniqueID = 35,
|
||||
TabletProximityEventCapabilityMask = 36,
|
||||
TabletProximityEventPointerType = 37,
|
||||
TabletProximityEventEnterProximity = 38,
|
||||
EventTargetProcessSerialNumber = 39,
|
||||
EventTargetUnixProcessID = 40,
|
||||
EventSourceUnixProcessID = 41,
|
||||
EventSourceUserData = 42,
|
||||
EventSourceUserID = 43,
|
||||
EventSourceGroupID = 44,
|
||||
EventSourceStateID = 45,
|
||||
ScrollWheelEventIsContinuous = 88
|
||||
}
|
||||
}
|
||||
|
209
GLWidget/OpenTK/Platform/MacOS/QuartzDisplayDeviceDriver.cs
Normal file
209
GLWidget/OpenTK/Platform/MacOS/QuartzDisplayDeviceDriver.cs
Normal file
|
@ -0,0 +1,209 @@
|
|||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2010 the Open Toolkit library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using OpenTK.Platform.MacOS.Carbon;
|
||||
|
||||
namespace OpenTK.Platform.MacOS
|
||||
{
|
||||
internal sealed class QuartzDisplayDeviceDriver : DisplayDeviceBase
|
||||
{
|
||||
private static object display_lock = new object();
|
||||
|
||||
public QuartzDisplayDeviceDriver()
|
||||
{
|
||||
lock (display_lock)
|
||||
{
|
||||
// To minimize the need to add static methods to OpenTK.Graphics.DisplayDevice
|
||||
// we only allow settings to be set through its constructor.
|
||||
// Thus, we save all necessary parameters in temporary variables
|
||||
// and construct the device when every needed detail is available.
|
||||
// The main DisplayDevice constructor adds the newly constructed device
|
||||
// to the list of available devices.
|
||||
const int maxDisplayCount = 20;
|
||||
IntPtr[] displays = new IntPtr[maxDisplayCount];
|
||||
int displayCount;
|
||||
|
||||
unsafe
|
||||
{
|
||||
fixed (IntPtr* displayPtr = displays)
|
||||
{
|
||||
CG.GetActiveDisplayList(maxDisplayCount, displayPtr, out displayCount);
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Print("CoreGraphics reported {0} display(s).", displayCount);
|
||||
Debug.Indent();
|
||||
|
||||
for (int i = 0; i < displayCount; i++)
|
||||
{
|
||||
IntPtr currentDisplay = displays[i];
|
||||
|
||||
// according to docs, first element in the array is always the
|
||||
// main display.
|
||||
bool primary = (i == 0);
|
||||
|
||||
// gets current settings
|
||||
int currentWidth = CG.DisplayPixelsWide(currentDisplay);
|
||||
int currentHeight = CG.DisplayPixelsHigh(currentDisplay);
|
||||
Debug.Print("Display {0} is at {1}x{2}", i, currentWidth, currentHeight);
|
||||
|
||||
IntPtr displayModesPtr = CG.DisplayAvailableModes(currentDisplay);
|
||||
CFArray displayModes = new CFArray(displayModesPtr);
|
||||
Debug.Print("Supports {0} display modes.", displayModes.Count);
|
||||
|
||||
DisplayResolution opentk_dev_current_res = null;
|
||||
List<DisplayResolution> opentk_dev_available_res = new List<DisplayResolution>();
|
||||
IntPtr currentModePtr = CG.DisplayCurrentMode(currentDisplay);
|
||||
CFDictionary currentMode = new CFDictionary(currentModePtr);
|
||||
|
||||
for (int j = 0; j < displayModes.Count; j++)
|
||||
{
|
||||
CFDictionary dict = new CFDictionary(displayModes[j]);
|
||||
|
||||
int width = (int)dict.GetNumberValue("Width");
|
||||
int height = (int)dict.GetNumberValue("Height");
|
||||
int bpp = (int)dict.GetNumberValue("BitsPerPixel");
|
||||
double freq = dict.GetNumberValue("RefreshRate");
|
||||
bool current = currentMode.Ref == dict.Ref;
|
||||
|
||||
if (freq <= 0)
|
||||
{
|
||||
IntPtr displayLink;
|
||||
CV.DisplayLinkCreateWithCGDisplay(currentDisplay, out displayLink);
|
||||
|
||||
CVTime t = CV.DisplayLinkGetNominalOutputVideoRefreshPeriod(displayLink);
|
||||
if ((t.flags & (Int32)CV.TimeFlags.TimeIsIndefinite) != (Int32)CV.TimeFlags.TimeIsIndefinite)
|
||||
{
|
||||
freq = (double)t.timeScale / t.timeValue;
|
||||
}
|
||||
|
||||
CV.DisplayLinkRelease(displayLink);
|
||||
}
|
||||
|
||||
//if (current) Debug.Write(" * ");
|
||||
//else Debug.Write(" ");
|
||||
|
||||
//Debug.Print("Mode {0} is {1}x{2}x{3} @ {4}.", j, width, height, bpp, freq);
|
||||
|
||||
DisplayResolution thisRes = new DisplayResolution(0, 0, width, height, bpp, (float)freq);
|
||||
opentk_dev_available_res.Add(thisRes);
|
||||
|
||||
if (current)
|
||||
{
|
||||
opentk_dev_current_res = thisRes;
|
||||
}
|
||||
}
|
||||
|
||||
NSRect bounds = CG.DisplayBounds(currentDisplay);
|
||||
Rectangle newRect = new Rectangle((int)bounds.Location.X, (int)bounds.Location.Y, (int)bounds.Size.Width, (int)bounds.Size.Height);
|
||||
|
||||
Debug.Print("Display {0} bounds: {1}", i, newRect);
|
||||
|
||||
DisplayDevice opentk_dev = new DisplayDevice(opentk_dev_current_res,
|
||||
primary, opentk_dev_available_res, newRect, currentDisplay);
|
||||
|
||||
AvailableDevices.Add(opentk_dev);
|
||||
|
||||
if (primary)
|
||||
{
|
||||
Primary = opentk_dev;
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Unindent();
|
||||
}
|
||||
}
|
||||
|
||||
static internal IntPtr HandleTo(DisplayDevice displayDevice)
|
||||
{
|
||||
return (IntPtr)displayDevice.Id;
|
||||
}
|
||||
|
||||
private Dictionary<IntPtr, IntPtr> storedModes = new Dictionary<IntPtr, IntPtr>();
|
||||
private List<IntPtr> displaysCaptured = new List<IntPtr>();
|
||||
|
||||
public sealed override bool TryChangeResolution(DisplayDevice device, DisplayResolution resolution)
|
||||
{
|
||||
IntPtr display = HandleTo(device);
|
||||
IntPtr currentModePtr = CG.DisplayCurrentMode(display);
|
||||
|
||||
if (storedModes.ContainsKey(display) == false)
|
||||
{
|
||||
storedModes.Add(display, currentModePtr);
|
||||
}
|
||||
|
||||
IntPtr displayModesPtr = CG.DisplayAvailableModes(display);
|
||||
CFArray displayModes = new CFArray(displayModesPtr);
|
||||
|
||||
for (int j = 0; j < displayModes.Count; j++)
|
||||
{
|
||||
CFDictionary dict = new CFDictionary(displayModes[j]);
|
||||
|
||||
int width = (int)dict.GetNumberValue("Width");
|
||||
int height = (int)dict.GetNumberValue("Height");
|
||||
int bpp = (int)dict.GetNumberValue("BitsPerPixel");
|
||||
double freq = dict.GetNumberValue("RefreshRate");
|
||||
|
||||
if (width == resolution.Width && height == resolution.Height && bpp == resolution.BitsPerPixel && System.Math.Abs(freq - resolution.RefreshRate) < 1e-6)
|
||||
{
|
||||
// if (displaysCaptured.Contains(display) == false)
|
||||
// {
|
||||
// CG.DisplayCapture(display);
|
||||
// }
|
||||
|
||||
Debug.Print("Changing resolution to {0}x{1}x{2}@{3}.", width, height, bpp, freq);
|
||||
|
||||
CG.DisplaySwitchToMode(display, displayModes[j]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public sealed override bool TryRestoreResolution(DisplayDevice device)
|
||||
{
|
||||
IntPtr display = HandleTo(device);
|
||||
|
||||
if (storedModes.ContainsKey(display))
|
||||
{
|
||||
Debug.Print("Restoring resolution.");
|
||||
|
||||
CG.DisplaySwitchToMode(display, storedModes[display]);
|
||||
//CG.DisplayRelease(display);
|
||||
displaysCaptured.Remove(display);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
29
GLWidget/OpenTK/Platform/PlatformException.cs
Normal file
29
GLWidget/OpenTK/Platform/PlatformException.cs
Normal file
|
@ -0,0 +1,29 @@
|
|||
/* Licensed under the MIT/X11 license.
|
||||
* Copyright (c) 2006-2008 the OpenTK Team.
|
||||
* This notice may not be removed from any source distribution.
|
||||
* See license.txt for licensing detailed licensing details.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace OpenTK
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a plaftorm-specific exception.
|
||||
/// </summary>
|
||||
public class PlatformException : Exception
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="OpenTK.PlatformException"/> class.
|
||||
/// </summary>
|
||||
public PlatformException()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="OpenTK.PlatformException"/> class.
|
||||
/// </summary>
|
||||
/// <param name="message">A message explaining the cause for this exception.</param>
|
||||
public PlatformException(string message) : base(message) { }
|
||||
}
|
||||
}
|
106
GLWidget/OpenTK/Platform/PlatformFactoryBase.cs
Normal file
106
GLWidget/OpenTK/Platform/PlatformFactoryBase.cs
Normal file
|
@ -0,0 +1,106 @@
|
|||
//
|
||||
// PlatformFactoryBase.cs
|
||||
//
|
||||
// Author:
|
||||
// Stefanos A. <stapostol@gmail.com>
|
||||
//
|
||||
// Copyright (c) 2006-2014 Stefanos Apostolopoulos
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace OpenTK.Platform
|
||||
{
|
||||
/// \internal
|
||||
/// <summary>
|
||||
/// Implements IPlatformFactory functionality that is common
|
||||
/// for all platform backends. IPlatformFactory implementations
|
||||
/// should inherit from this class.
|
||||
/// </summary>
|
||||
internal abstract class PlatformFactoryBase : IPlatformFactory
|
||||
{
|
||||
private static readonly object sync = new object();
|
||||
private readonly List<IDisposable> Resources = new List<IDisposable>();
|
||||
|
||||
protected bool IsDisposed;
|
||||
|
||||
public PlatformFactoryBase()
|
||||
{
|
||||
}
|
||||
public abstract IDisplayDeviceDriver CreateDisplayDeviceDriver();
|
||||
|
||||
public abstract IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags);
|
||||
|
||||
public virtual IGraphicsContext CreateGLContext(ContextHandle handle, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public abstract GraphicsContext.GetCurrentContextDelegate CreateGetCurrentGraphicsContext();
|
||||
|
||||
public void RegisterResource(IDisposable resource)
|
||||
{
|
||||
lock (sync)
|
||||
{
|
||||
Resources.Add(resource);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool manual)
|
||||
{
|
||||
if (!IsDisposed)
|
||||
{
|
||||
if (manual)
|
||||
{
|
||||
lock (sync)
|
||||
{
|
||||
foreach (var resource in Resources)
|
||||
{
|
||||
resource.Dispose();
|
||||
}
|
||||
Resources.Clear();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Print("[OpenTK] {0} leaked with {1} live resources, did you forget to call Dispose()?",
|
||||
GetType().FullName, Resources.Count);
|
||||
}
|
||||
IsDisposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
~PlatformFactoryBase()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
401
GLWidget/OpenTK/Platform/Utilities.cs
Normal file
401
GLWidget/OpenTK/Platform/Utilities.cs
Normal file
|
@ -0,0 +1,401 @@
|
|||
/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos
|
||||
* See license.txt for license info
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Diagnostics;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace OpenTK.Platform
|
||||
{
|
||||
namespace MacOS
|
||||
{
|
||||
/// <summary>
|
||||
/// This delegate represents any method that takes no arguments and returns an int.
|
||||
/// I would have used Func but that requires .NET 4
|
||||
/// </summary>
|
||||
/// <returns>The int value that your method returns</returns>
|
||||
public delegate int GetInt();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides cross-platform utilities to help interact with the underlying platform.
|
||||
/// </summary>
|
||||
public static class Utilities
|
||||
{
|
||||
private static bool throw_on_error;
|
||||
internal static bool ThrowOnX11Error
|
||||
{
|
||||
get { return throw_on_error; }
|
||||
set
|
||||
{
|
||||
if (value && !throw_on_error)
|
||||
{
|
||||
Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms")
|
||||
.GetField("ErrorExceptions", System.Reflection.BindingFlags.Static |
|
||||
System.Reflection.BindingFlags.NonPublic)
|
||||
.SetValue(null, true);
|
||||
throw_on_error = true;
|
||||
}
|
||||
else if (!value && throw_on_error)
|
||||
{
|
||||
Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms")
|
||||
.GetField("ErrorExceptions", System.Reflection.BindingFlags.Static |
|
||||
System.Reflection.BindingFlags.NonPublic)
|
||||
.SetValue(null, false);
|
||||
throw_on_error = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private delegate Delegate LoadDelegateFunction(string name, Type signature);
|
||||
|
||||
/// <internal />
|
||||
/// <summary>Loads all extensions for the specified class. This function is intended
|
||||
/// for OpenGL, Wgl, Glx, OpenAL etc.</summary>
|
||||
/// <param name="type">The class to load extensions for.</param>
|
||||
/// <remarks>
|
||||
/// <para>The Type must contain a nested class called "Delegates".</para>
|
||||
/// <para>
|
||||
/// The Type must also implement a static function called LoadDelegate with the
|
||||
/// following signature:
|
||||
/// <code>static Delegate LoadDelegate(string name, Type signature)</code>
|
||||
/// </para>
|
||||
/// <para>This function allocates memory.</para>
|
||||
/// </remarks>
|
||||
internal static void LoadExtensions(Type type)
|
||||
{
|
||||
// Using reflection is more than 3 times faster than directly loading delegates on the first
|
||||
// run, probably due to code generation overhead. Subsequent runs are faster with direct loading
|
||||
// than with reflection, but the first time is more significant.
|
||||
|
||||
int supported = 0;
|
||||
Type extensions_class = type.GetNestedType("Delegates", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
|
||||
if (extensions_class == null)
|
||||
{
|
||||
throw new InvalidOperationException("The specified type does not have any loadable extensions.");
|
||||
}
|
||||
|
||||
FieldInfo[] delegates = extensions_class.GetFields(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
|
||||
if (delegates == null)
|
||||
{
|
||||
throw new InvalidOperationException("The specified type does not have any loadable extensions.");
|
||||
}
|
||||
|
||||
MethodInfo load_delegate_method_info = type.GetMethod("LoadDelegate", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
|
||||
if (load_delegate_method_info == null)
|
||||
{
|
||||
throw new InvalidOperationException(type.ToString() + " does not contain a static LoadDelegate method.");
|
||||
}
|
||||
LoadDelegateFunction LoadDelegate = (LoadDelegateFunction)Delegate.CreateDelegate(
|
||||
typeof(LoadDelegateFunction), load_delegate_method_info);
|
||||
|
||||
Debug.Write("Load extensions for " + type.ToString() + "... ");
|
||||
|
||||
System.Diagnostics.Stopwatch time = new System.Diagnostics.Stopwatch();
|
||||
time.Reset();
|
||||
time.Start();
|
||||
|
||||
foreach (FieldInfo f in delegates)
|
||||
{
|
||||
Delegate d = LoadDelegate(f.Name, f.FieldType);
|
||||
if (d != null)
|
||||
{
|
||||
++supported;
|
||||
}
|
||||
|
||||
f.SetValue(null, d);
|
||||
}
|
||||
|
||||
FieldInfo rebuildExtensionList = type.GetField("rebuildExtensionList", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
|
||||
if (rebuildExtensionList != null)
|
||||
{
|
||||
rebuildExtensionList.SetValue(null, true);
|
||||
}
|
||||
|
||||
time.Stop();
|
||||
Debug.Print("{0} extensions loaded in {1} ms.", supported, time.ElapsedMilliseconds);
|
||||
time.Reset();
|
||||
}
|
||||
|
||||
/// <internal />
|
||||
/// <summary>Loads the specified extension for the specified class. This function is intended
|
||||
/// for OpenGL, Wgl, Glx, OpenAL etc.</summary>
|
||||
/// <param name="type">The class to load extensions for.</param>
|
||||
/// <param name="extension">The extension to load.</param>
|
||||
/// <remarks>
|
||||
/// <para>The Type must contain a nested class called "Delegates".</para>
|
||||
/// <para>
|
||||
/// The Type must also implement a static function called LoadDelegate with the
|
||||
/// following signature:
|
||||
/// <code>static Delegate LoadDelegate(string name, Type signature)</code>
|
||||
/// </para>
|
||||
/// <para>This function allocates memory.</para>
|
||||
/// </remarks>
|
||||
internal static bool TryLoadExtension(Type type, string extension)
|
||||
{
|
||||
Type extensions_class = type.GetNestedType("Delegates", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
|
||||
if (extensions_class == null)
|
||||
{
|
||||
Debug.Print(type.ToString(), " does not contain extensions.");
|
||||
return false;
|
||||
}
|
||||
|
||||
LoadDelegateFunction LoadDelegate = (LoadDelegateFunction)Delegate.CreateDelegate(typeof(LoadDelegateFunction),
|
||||
type.GetMethod("LoadDelegate", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public));
|
||||
if (LoadDelegate == null)
|
||||
{
|
||||
Debug.Print(type.ToString(), " does not contain a static LoadDelegate method.");
|
||||
return false;
|
||||
}
|
||||
|
||||
FieldInfo f = extensions_class.GetField(extension, BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
|
||||
if (f == null)
|
||||
{
|
||||
Debug.Print("Extension \"", extension, "\" not found in ", type.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
Delegate old = f.GetValue(null) as Delegate;
|
||||
Delegate @new = LoadDelegate(f.Name, f.FieldType);
|
||||
if ((old != null ? old.Target : null) != (@new != null ? @new.Target : null))
|
||||
{
|
||||
f.SetValue(null, @new);
|
||||
FieldInfo rebuildExtensionList = type.GetField("rebuildExtensionList", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
|
||||
if (rebuildExtensionList != null)
|
||||
{
|
||||
rebuildExtensionList.SetValue(null, true);
|
||||
}
|
||||
}
|
||||
return @new != null;
|
||||
}
|
||||
|
||||
internal static GraphicsContext.GetAddressDelegate CreateGetAddress()
|
||||
{
|
||||
if (Configuration.RunningOnWindows)
|
||||
{
|
||||
return Platform.Windows.Wgl.GetAddress;
|
||||
}
|
||||
if (Configuration.RunningOnX11)
|
||||
{
|
||||
return Platform.X11.Glx.GetProcAddress;
|
||||
}
|
||||
if (Configuration.RunningOnMacOS)
|
||||
{
|
||||
return Platform.MacOS.NS.GetAddress;
|
||||
}
|
||||
|
||||
// Other platforms: still allow dummy contexts to be created (if no Loader is required)
|
||||
return EmptyGetAddress;
|
||||
}
|
||||
|
||||
private static IntPtr EmptyGetAddress(string function)
|
||||
{
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new IWindowInfo instance for the X11 platform.
|
||||
/// </summary>
|
||||
/// <param name="display">The display connection.</param>
|
||||
/// <param name="screen">The screen.</param>
|
||||
/// <param name="windowHandle">The handle for the window.</param>
|
||||
/// <param name="rootWindow">The root window for screen.</param>
|
||||
/// <param name="visualInfo">A pointer to a XVisualInfo structure obtained through XGetVisualInfo.</param>
|
||||
/// <returns>A new IWindowInfo instance.</returns>
|
||||
public static IWindowInfo CreateX11WindowInfo(IntPtr display, int screen, IntPtr windowHandle, IntPtr rootWindow, IntPtr visualInfo)
|
||||
{
|
||||
Platform.X11.X11WindowInfo window = new OpenTK.Platform.X11.X11WindowInfo();
|
||||
window.Display = display;
|
||||
window.Screen = screen;
|
||||
window.Handle = windowHandle;
|
||||
window.RootWindow = rootWindow;
|
||||
window.Visual = visualInfo;
|
||||
return window;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an IWindowInfo instance for the windows platform.
|
||||
/// </summary>
|
||||
/// <param name="windowHandle">The handle of the window.</param>
|
||||
/// <returns>A new IWindowInfo instance.</returns>
|
||||
public static IWindowInfo CreateWindowsWindowInfo(IntPtr windowHandle)
|
||||
{
|
||||
return new OpenTK.Platform.Windows.WinWindowInfo(windowHandle, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an IWindowInfo instance for the Mac OS X platform.
|
||||
/// </summary>
|
||||
/// <param name="windowHandle">The handle of the window.</param>
|
||||
/// <param name="ownHandle">Ignored. This is reserved for future use.</param>
|
||||
/// <param name="isControl">Set to true if windowHandle corresponds to a System.Windows.Forms control.</param>
|
||||
/// <returns>A new IWindowInfo instance.</returns>
|
||||
public static IWindowInfo CreateMacOSCarbonWindowInfo(IntPtr windowHandle, bool ownHandle, bool isControl)
|
||||
{
|
||||
return CreateMacOSCarbonWindowInfo(windowHandle, ownHandle, isControl, null, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an IWindowInfo instance for the Mac OS X platform with an X and Y offset for the GL viewport location.
|
||||
/// </summary>
|
||||
/// <param name="windowHandle">The handle of the window.</param>
|
||||
/// <param name="ownHandle">Ignored. This is reserved for future use.</param>
|
||||
/// <param name="isControl">Set to true if windowHandle corresponds to a System.Windows.Forms control.</param>
|
||||
/// <param name="xOffset">The X offset for the GL viewport</param>
|
||||
/// <param name="yOffset">The Y offset for the GL viewport</param>
|
||||
/// <returns>A new IWindowInfo instance.</returns>
|
||||
public static IWindowInfo CreateMacOSCarbonWindowInfo(IntPtr windowHandle, bool ownHandle, bool isControl,
|
||||
OpenTK.Platform.MacOS.GetInt xOffset, OpenTK.Platform.MacOS.GetInt yOffset)
|
||||
{
|
||||
return new OpenTK.Platform.MacOS.CarbonWindowInfo(windowHandle, false, isControl, xOffset, yOffset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an IWindowInfo instance for the Mac OS X platform.
|
||||
/// </summary>
|
||||
/// <param name="windowHandle">The handle of the NSWindow.</param>
|
||||
/// <remarks>Assumes that the NSWindow's contentView is the NSView we want to attach to our context.</remarks>
|
||||
/// <returns>A new IWindowInfo instance.</returns>
|
||||
public static IWindowInfo CreateMacOSWindowInfo(IntPtr windowHandle)
|
||||
{
|
||||
return new OpenTK.Platform.MacOS.CocoaWindowInfo(windowHandle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an IWindowInfo instance for the Mac OS X platform.
|
||||
/// </summary>
|
||||
/// <param name="windowHandle">The handle of the NSWindow.</param>
|
||||
/// <param name="viewHandle">The handle of the NSView.</param>
|
||||
/// <returns>A new IWindowInfo instance.</returns>
|
||||
public static IWindowInfo CreateMacOSWindowInfo(IntPtr windowHandle, IntPtr viewHandle)
|
||||
{
|
||||
return new OpenTK.Platform.MacOS.CocoaWindowInfo(windowHandle, viewHandle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an IWindowInfo instance for the dummy platform.
|
||||
/// </summary>
|
||||
/// <returns>A new IWindowInfo instance.</returns>
|
||||
public static IWindowInfo CreateDummyWindowInfo()
|
||||
{
|
||||
return new Dummy.DummyWindowInfo();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an IWindowInfo instance for Angle rendering, based on
|
||||
/// supplied platform window (e.g. a window created with
|
||||
/// CreateWindowsWindowInfo, or CreateDummyWindowInfo).
|
||||
/// </summary>
|
||||
/// <param name="platformWindow"></param>
|
||||
/// <returns></returns>
|
||||
public static Egl.IAngleWindowInfo CreateAngleWindowInfo(IWindowInfo platformWindow)
|
||||
{
|
||||
return new Egl.AngleWindowInfo(platformWindow);
|
||||
}
|
||||
internal static bool RelaxGraphicsMode(ref GraphicsMode mode)
|
||||
{
|
||||
ColorFormat color = mode.ColorFormat;
|
||||
int depth = mode.Depth;
|
||||
int stencil = mode.Stencil;
|
||||
int samples = mode.Samples;
|
||||
ColorFormat accum = mode.AccumulatorFormat;
|
||||
int buffers = mode.Buffers;
|
||||
bool stereo = mode.Stereo;
|
||||
|
||||
bool success = RelaxGraphicsMode(
|
||||
ref color, ref depth, ref stencil, ref samples,
|
||||
ref accum, ref buffers, ref stereo);
|
||||
|
||||
mode = new GraphicsMode(
|
||||
color, depth, stencil, samples,
|
||||
accum, buffers, stereo);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/// \internal
|
||||
/// <summary>
|
||||
/// Relaxes graphics mode parameters. Use this function to increase compatibility
|
||||
/// on systems that do not directly support a requested GraphicsMode. For example:
|
||||
/// - user requested stereoscopic rendering, but GPU does not support stereo
|
||||
/// - user requseted 16x antialiasing, but GPU only supports 4x
|
||||
/// </summary>
|
||||
/// <returns><c>true</c>, if a graphics mode parameter was relaxed, <c>false</c> otherwise.</returns>
|
||||
/// <param name="color">Color bits.</param>
|
||||
/// <param name="depth">Depth bits.</param>
|
||||
/// <param name="stencil">Stencil bits.</param>
|
||||
/// <param name="samples">Number of antialiasing samples.</param>
|
||||
/// <param name="accum">Accumulator buffer bits.</param>
|
||||
/// <param name="buffers">Number of rendering buffers (1 for single buffering, 2+ for double buffering, 0 for don't care).</param>
|
||||
/// <param name="stereo">Stereoscopic rendering enabled/disabled.</param>
|
||||
internal static bool RelaxGraphicsMode(ref ColorFormat color, ref int depth, ref int stencil, ref int samples, ref ColorFormat accum, ref int buffers, ref bool stereo)
|
||||
{
|
||||
// Parameters are relaxed in order of importance.
|
||||
// - Accumulator buffers are way outdated as a concept,
|
||||
// so they go first.
|
||||
// - Triple+ buffering is generally not supported by the
|
||||
// core WGL/GLX/AGL/CGL/EGL specs, so we clamp
|
||||
// to double-buffering as a second step. (If this doesn't help
|
||||
// we will also fall back to undefined single/double buffering
|
||||
// as a last resort).
|
||||
// - AA samples are an easy way to increase compatibility
|
||||
// so they go next.
|
||||
// - Stereoscopic is only supported on very few GPUs
|
||||
// (Quadro/FirePro series) so it goes next.
|
||||
// - The rest of the parameters then follow.
|
||||
|
||||
if (accum != 0)
|
||||
{
|
||||
accum = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (buffers > 2)
|
||||
{
|
||||
buffers = 2;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (samples > 0)
|
||||
{
|
||||
samples = Math.Max(samples - 1, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (stereo)
|
||||
{
|
||||
stereo = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (stencil != 0)
|
||||
{
|
||||
stencil = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (depth != 0)
|
||||
{
|
||||
depth = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (color != 24)
|
||||
{
|
||||
color = 24;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (buffers != 0)
|
||||
{
|
||||
buffers = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
// no parameters left to relax, fail
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
3012
GLWidget/OpenTK/Platform/Windows/API.cs
Normal file
3012
GLWidget/OpenTK/Platform/Windows/API.cs
Normal file
File diff suppressed because it is too large
Load diff
159
GLWidget/OpenTK/Platform/Windows/Bindings/Wgl.cs
Normal file
159
GLWidget/OpenTK/Platform/Windows/Bindings/Wgl.cs
Normal file
|
@ -0,0 +1,159 @@
|
|||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2013 Stefanos Apostolopoulos
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using OpenTK.Core.Native;
|
||||
|
||||
namespace OpenTK.Platform.Windows
|
||||
{
|
||||
#pragma warning disable 3019
|
||||
#pragma warning disable 1591
|
||||
|
||||
internal partial class Wgl
|
||||
{
|
||||
static Wgl()
|
||||
{
|
||||
EntryPointNames = new string[]
|
||||
{
|
||||
"wglCreateContextAttribsARB",
|
||||
"wglGetExtensionsStringARB",
|
||||
"wglGetPixelFormatAttribivARB",
|
||||
"wglGetPixelFormatAttribfvARB",
|
||||
"wglChoosePixelFormatARB",
|
||||
"wglMakeContextCurrentARB",
|
||||
"wglGetCurrentReadDCARB",
|
||||
"wglCreatePbufferARB",
|
||||
"wglGetPbufferDCARB",
|
||||
"wglReleasePbufferDCARB",
|
||||
"wglDestroyPbufferARB",
|
||||
"wglQueryPbufferARB",
|
||||
"wglBindTexImageARB",
|
||||
"wglReleaseTexImageARB",
|
||||
"wglSetPbufferAttribARB",
|
||||
"wglGetExtensionsStringEXT",
|
||||
"wglSwapIntervalEXT",
|
||||
"wglGetSwapIntervalEXT",
|
||||
};
|
||||
EntryPoints = new IntPtr[EntryPointNames.Length];
|
||||
}
|
||||
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[DllImport(Wgl.Library, EntryPoint = "wglCreateContext", ExactSpelling = true, SetLastError = true)]
|
||||
internal extern static IntPtr CreateContext(IntPtr hDc);
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[DllImport(Wgl.Library, EntryPoint = "wglDeleteContext", ExactSpelling = true, SetLastError = true)]
|
||||
internal extern static Boolean DeleteContext(IntPtr oldContext);
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[DllImport(Wgl.Library, EntryPoint = "wglGetCurrentContext", ExactSpelling = true, SetLastError = true)]
|
||||
internal extern static IntPtr GetCurrentContext();
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[DllImport(Wgl.Library, EntryPoint = "wglMakeCurrent", ExactSpelling = true, SetLastError = true)]
|
||||
internal extern static Boolean MakeCurrent(IntPtr hDc, IntPtr newContext);
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[DllImport(Wgl.Library, EntryPoint = "wglChoosePixelFormat", ExactSpelling = true, SetLastError = true)]
|
||||
internal extern static unsafe int ChoosePixelFormat(IntPtr hDc, ref PixelFormatDescriptor pPfd);
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[DllImport(Wgl.Library, EntryPoint = "wglDescribePixelFormat", ExactSpelling = true, SetLastError = true)]
|
||||
internal extern static unsafe int DescribePixelFormat(IntPtr hdc, int ipfd, int cjpfd, ref PixelFormatDescriptor ppfd);
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[DllImport(Wgl.Library, EntryPoint = "wglGetCurrentDC", ExactSpelling = true, SetLastError = true)]
|
||||
internal extern static IntPtr GetCurrentDC();
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[DllImport(Wgl.Library, EntryPoint = "wglGetProcAddress", ExactSpelling = true, SetLastError = true)]
|
||||
internal extern static IntPtr GetProcAddress(String lpszProc);
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[DllImport(Wgl.Library, EntryPoint = "wglGetProcAddress", ExactSpelling = true, SetLastError = true)]
|
||||
internal extern static IntPtr GetProcAddress(IntPtr lpszProc);
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[DllImport(Wgl.Library, EntryPoint = "wglGetPixelFormat", ExactSpelling = true, SetLastError = true)]
|
||||
internal extern static int GetPixelFormat(IntPtr hdc);
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[DllImport(Wgl.Library, EntryPoint = "wglSetPixelFormat", ExactSpelling = true, SetLastError = true)]
|
||||
internal extern static Boolean SetPixelFormat(IntPtr hdc, int ipfd, ref PixelFormatDescriptor ppfd);
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[DllImport(Wgl.Library, EntryPoint = "wglSwapBuffers", ExactSpelling = true, SetLastError = true)]
|
||||
internal extern static Boolean SwapBuffers(IntPtr hdc);
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[DllImport(Wgl.Library, EntryPoint = "wglShareLists", ExactSpelling = true, SetLastError = true)]
|
||||
internal extern static Boolean ShareLists(IntPtr hrcSrvShare, IntPtr hrcSrvSource);
|
||||
|
||||
[Slot(0)]
|
||||
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
||||
internal unsafe static extern IntPtr wglCreateContextAttribsARB(IntPtr hDC, IntPtr hShareContext, int* attribList);
|
||||
[Slot(1)]
|
||||
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
||||
internal static extern IntPtr wglGetExtensionsStringARB(IntPtr hdc);
|
||||
[Slot(2)]
|
||||
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
||||
internal unsafe static extern Boolean wglGetPixelFormatAttribivARB(IntPtr hdc, int iPixelFormat, int iLayerPlane, UInt32 nAttributes, int* piAttributes, [Out] int* piValues);
|
||||
[Slot(3)]
|
||||
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
||||
internal unsafe static extern Boolean wglGetPixelFormatAttribfvARB(IntPtr hdc, int iPixelFormat, int iLayerPlane, UInt32 nAttributes, int* piAttributes, [Out] Single* pfValues);
|
||||
[Slot(4)]
|
||||
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
||||
internal unsafe static extern Boolean wglChoosePixelFormatARB(IntPtr hdc, int* piAttribIList, Single* pfAttribFList, UInt32 nMaxFormats, [Out] int* piFormats, [Out] UInt32* nNumFormats);
|
||||
[Slot(5)]
|
||||
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
||||
internal static extern Boolean wglMakeContextCurrentARB(IntPtr hDrawDC, IntPtr hReadDC, IntPtr hglrc);
|
||||
[Slot(6)]
|
||||
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
||||
internal static extern IntPtr wglGetCurrentReadDCARB();
|
||||
[Slot(7)]
|
||||
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
||||
internal unsafe static extern IntPtr wglCreatePbufferARB(IntPtr hDC, int iPixelFormat, int iWidth, int iHeight, int* piAttribList);
|
||||
[Slot(8)]
|
||||
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
||||
internal static extern IntPtr wglGetPbufferDCARB(IntPtr hPbuffer);
|
||||
[Slot(9)]
|
||||
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
||||
internal static extern int wglReleasePbufferDCARB(IntPtr hPbuffer, IntPtr hDC);
|
||||
[Slot(10)]
|
||||
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
||||
internal static extern Boolean wglDestroyPbufferARB(IntPtr hPbuffer);
|
||||
[Slot(11)]
|
||||
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
||||
internal unsafe static extern Boolean wglQueryPbufferARB(IntPtr hPbuffer, int iAttribute, [Out] int* piValue);
|
||||
[Slot(12)]
|
||||
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
||||
internal static extern Boolean wglBindTexImageARB(IntPtr hPbuffer, int iBuffer);
|
||||
[Slot(13)]
|
||||
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
||||
internal static extern Boolean wglReleaseTexImageARB(IntPtr hPbuffer, int iBuffer);
|
||||
[Slot(14)]
|
||||
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
||||
internal unsafe static extern Boolean wglSetPbufferAttribARB(IntPtr hPbuffer, int* piAttribList);
|
||||
[Slot(15)]
|
||||
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
||||
internal static extern IntPtr wglGetExtensionsStringEXT();
|
||||
[Slot(16)]
|
||||
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
||||
internal static extern Boolean wglSwapIntervalEXT(int interval);
|
||||
[Slot(17)]
|
||||
[DllImport(Library, ExactSpelling = true, CallingConvention = CallingConvention.Winapi)]
|
||||
internal static extern int wglGetSwapIntervalEXT();
|
||||
}
|
||||
}
|
521
GLWidget/OpenTK/Platform/Windows/Bindings/WglEnums.cs
Normal file
521
GLWidget/OpenTK/Platform/Windows/Bindings/WglEnums.cs
Normal file
|
@ -0,0 +1,521 @@
|
|||
namespace OpenTK.Platform.Windows
|
||||
{
|
||||
#pragma warning disable 3019
|
||||
#pragma warning disable 1591
|
||||
|
||||
public enum ArbCreateContext
|
||||
{
|
||||
CoreProfileBit = 0x0001,
|
||||
CompatibilityProfileBit = 0x0002,
|
||||
DebugBit = 0x0001,
|
||||
ForwardCompatibleBit = 0x0002,
|
||||
MajorVersion = 0x2091,
|
||||
MinorVersion = 0x2092,
|
||||
LayerPlane = 0x2093,
|
||||
ContextFlags = 0x2094,
|
||||
ErrorInvalidVersion = 0x2095,
|
||||
ProfileMask = 0x9126
|
||||
}
|
||||
|
||||
public enum WGL_ARB_buffer_region
|
||||
{
|
||||
BackColorBufferBitArb = ((int)0x00000002),
|
||||
StencilBufferBitArb = ((int)0x00000008),
|
||||
FrontColorBufferBitArb = ((int)0x00000001),
|
||||
DepthBufferBitArb = ((int)0x00000004),
|
||||
}
|
||||
|
||||
public enum WGL_EXT_pixel_format
|
||||
{
|
||||
SupportGdiExt = ((int)0x200f),
|
||||
TypeColorindexExt = ((int)0x202c),
|
||||
AccelerationExt = ((int)0x2003),
|
||||
GreenBitsExt = ((int)0x2017),
|
||||
DrawToWindowExt = ((int)0x2001),
|
||||
SwapCopyExt = ((int)0x2029),
|
||||
DrawToBitmapExt = ((int)0x2002),
|
||||
TransparentExt = ((int)0x200a),
|
||||
SwapMethodExt = ((int)0x2007),
|
||||
SwapLayerBuffersExt = ((int)0x2006),
|
||||
PixelTypeExt = ((int)0x2013),
|
||||
AlphaShiftExt = ((int)0x201c),
|
||||
AccumRedBitsExt = ((int)0x201e),
|
||||
FullAccelerationExt = ((int)0x2027),
|
||||
SupportOpenglExt = ((int)0x2010),
|
||||
BlueShiftExt = ((int)0x201a),
|
||||
RedBitsExt = ((int)0x2015),
|
||||
NoAccelerationExt = ((int)0x2025),
|
||||
StereoExt = ((int)0x2012),
|
||||
GreenShiftExt = ((int)0x2018),
|
||||
BlueBitsExt = ((int)0x2019),
|
||||
AlphaBitsExt = ((int)0x201b),
|
||||
RedShiftExt = ((int)0x2016),
|
||||
DepthBitsExt = ((int)0x2022),
|
||||
TypeRgbaExt = ((int)0x202b),
|
||||
GenericAccelerationExt = ((int)0x2026),
|
||||
AccumAlphaBitsExt = ((int)0x2021),
|
||||
AccumGreenBitsExt = ((int)0x201f),
|
||||
TransparentValueExt = ((int)0x200b),
|
||||
AccumBlueBitsExt = ((int)0x2020),
|
||||
ShareDepthExt = ((int)0x200c),
|
||||
ShareAccumExt = ((int)0x200e),
|
||||
SwapExchangeExt = ((int)0x2028),
|
||||
AccumBitsExt = ((int)0x201d),
|
||||
NumberUnderlaysExt = ((int)0x2009),
|
||||
StencilBitsExt = ((int)0x2023),
|
||||
DoubleBufferExt = ((int)0x2011),
|
||||
NeedPaletteExt = ((int)0x2004),
|
||||
ColorBitsExt = ((int)0x2014),
|
||||
SwapUndefinedExt = ((int)0x202a),
|
||||
NeedSystemPaletteExt = ((int)0x2005),
|
||||
NumberOverlaysExt = ((int)0x2008),
|
||||
AuxBuffersExt = ((int)0x2024),
|
||||
NumberPixelFormatsExt = ((int)0x2000),
|
||||
ShareStencilExt = ((int)0x200d),
|
||||
}
|
||||
|
||||
public enum WGL_ARB_pixel_format
|
||||
{
|
||||
ShareStencilArb = ((int)0x200d),
|
||||
AccumBitsArb = ((int)0x201d),
|
||||
NumberUnderlaysArb = ((int)0x2009),
|
||||
StereoArb = ((int)0x2012),
|
||||
MaxPbufferHeightArb = ((int)0x2030),
|
||||
TypeRgbaArb = ((int)0x202b),
|
||||
SupportGdiArb = ((int)0x200f),
|
||||
NeedSystemPaletteArb = ((int)0x2005),
|
||||
AlphaBitsArb = ((int)0x201b),
|
||||
ShareDepthArb = ((int)0x200c),
|
||||
SupportOpenglArb = ((int)0x2010),
|
||||
ColorBitsArb = ((int)0x2014),
|
||||
AccumRedBitsArb = ((int)0x201e),
|
||||
MaxPbufferWidthArb = ((int)0x202f),
|
||||
NumberOverlaysArb = ((int)0x2008),
|
||||
MaxPbufferPixelsArb = ((int)0x202e),
|
||||
NeedPaletteArb = ((int)0x2004),
|
||||
RedShiftArb = ((int)0x2016),
|
||||
AccelerationArb = ((int)0x2003),
|
||||
GreenBitsArb = ((int)0x2017),
|
||||
TransparentGreenValueArb = ((int)0x2038),
|
||||
PixelTypeArb = ((int)0x2013),
|
||||
AuxBuffersArb = ((int)0x2024),
|
||||
DrawToWindowArb = ((int)0x2001),
|
||||
RedBitsArb = ((int)0x2015),
|
||||
NumberPixelFormatsArb = ((int)0x2000),
|
||||
GenericAccelerationArb = ((int)0x2026),
|
||||
BlueBitsArb = ((int)0x2019),
|
||||
PbufferLargestArb = ((int)0x2033),
|
||||
AccumAlphaBitsArb = ((int)0x2021),
|
||||
TransparentArb = ((int)0x200a),
|
||||
FullAccelerationArb = ((int)0x2027),
|
||||
ShareAccumArb = ((int)0x200e),
|
||||
SwapExchangeArb = ((int)0x2028),
|
||||
SwapUndefinedArb = ((int)0x202a),
|
||||
TransparentAlphaValueArb = ((int)0x203a),
|
||||
PbufferHeightArb = ((int)0x2035),
|
||||
TransparentBlueValueArb = ((int)0x2039),
|
||||
SwapMethodArb = ((int)0x2007),
|
||||
StencilBitsArb = ((int)0x2023),
|
||||
DepthBitsArb = ((int)0x2022),
|
||||
GreenShiftArb = ((int)0x2018),
|
||||
TransparentRedValueArb = ((int)0x2037),
|
||||
DoubleBufferArb = ((int)0x2011),
|
||||
NoAccelerationArb = ((int)0x2025),
|
||||
TypeColorindexArb = ((int)0x202c),
|
||||
SwapLayerBuffersArb = ((int)0x2006),
|
||||
AccumBlueBitsArb = ((int)0x2020),
|
||||
DrawToPbufferArb = ((int)0x202d),
|
||||
AccumGreenBitsArb = ((int)0x201f),
|
||||
PbufferWidthArb = ((int)0x2034),
|
||||
TransparentIndexValueArb = ((int)0x203b),
|
||||
AlphaShiftArb = ((int)0x201c),
|
||||
DrawToBitmapArb = ((int)0x2002),
|
||||
BlueShiftArb = ((int)0x201a),
|
||||
SwapCopyArb = ((int)0x2029),
|
||||
}
|
||||
|
||||
public enum WGL_EXT_pbuffer
|
||||
{
|
||||
DrawToPbufferExt = ((int)0x202d),
|
||||
PbufferLargestExt = ((int)0x2033),
|
||||
OptimalPbufferWidthExt = ((int)0x2031),
|
||||
MaxPbufferPixelsExt = ((int)0x202e),
|
||||
MaxPbufferHeightExt = ((int)0x2030),
|
||||
PbufferWidthExt = ((int)0x2034),
|
||||
MaxPbufferWidthExt = ((int)0x202f),
|
||||
OptimalPbufferHeightExt = ((int)0x2032),
|
||||
PbufferHeightExt = ((int)0x2035),
|
||||
}
|
||||
|
||||
public enum WGL_ARB_pbuffer
|
||||
{
|
||||
PbufferWidthArb = ((int)0x2034),
|
||||
TransparentGreenValueArb = ((int)0x2038),
|
||||
PbufferHeightArb = ((int)0x2035),
|
||||
PbufferLostArb = ((int)0x2036),
|
||||
DrawToPbufferArb = ((int)0x202d),
|
||||
TransparentIndexValueArb = ((int)0x203b),
|
||||
TransparentRedValueArb = ((int)0x2037),
|
||||
MaxPbufferPixelsArb = ((int)0x202e),
|
||||
TransparentAlphaValueArb = ((int)0x203a),
|
||||
MaxPbufferWidthArb = ((int)0x202f),
|
||||
MaxPbufferHeightArb = ((int)0x2030),
|
||||
TransparentBlueValueArb = ((int)0x2039),
|
||||
PbufferLargestArb = ((int)0x2033),
|
||||
}
|
||||
|
||||
public enum WGL_EXT_depth_float
|
||||
{
|
||||
DepthFloatExt = ((int)0x2040),
|
||||
}
|
||||
|
||||
public enum WGL_EXT_multisample
|
||||
{
|
||||
SampleBuffersExt = ((int)0x2041),
|
||||
SamplesExt = ((int)0x2042),
|
||||
}
|
||||
|
||||
public enum WGL_ARB_multisample
|
||||
{
|
||||
SampleBuffersArb = ((int)0x2041),
|
||||
SamplesArb = ((int)0x2042),
|
||||
}
|
||||
|
||||
public enum WGL_EXT_make_current_read
|
||||
{
|
||||
ErrorInvalidPixelTypeExt = ((int)0x2043),
|
||||
}
|
||||
|
||||
public enum WGL_ARB_make_current_read
|
||||
{
|
||||
ErrorInvalidPixelTypeArb = ((int)0x2043),
|
||||
ErrorIncompatibleDeviceContextsArb = ((int)0x2054),
|
||||
}
|
||||
|
||||
public enum WGL_I3D_genlock
|
||||
{
|
||||
GenlockSourceMultiviewI3d = ((int)0x2044),
|
||||
GenlockSourceEdgeBothI3d = ((int)0x204c),
|
||||
GenlockSourceEdgeRisingI3d = ((int)0x204b),
|
||||
GenlockSourceDigitalSyncI3d = ((int)0x2048),
|
||||
GenlockSourceExtenalFieldI3d = ((int)0x2046),
|
||||
GenlockSourceDigitalFieldI3d = ((int)0x2049),
|
||||
GenlockSourceExtenalSyncI3d = ((int)0x2045),
|
||||
GenlockSourceEdgeFallingI3d = ((int)0x204a),
|
||||
GenlockSourceExtenalTtlI3d = ((int)0x2047),
|
||||
}
|
||||
|
||||
public enum WGL_I3D_gamma
|
||||
{
|
||||
GammaExcludeDesktopI3d = ((int)0x204f),
|
||||
GammaTableSizeI3d = ((int)0x204e),
|
||||
}
|
||||
|
||||
public enum WGL_I3D_digital_video_control
|
||||
{
|
||||
DigitalVideoCursorAlphaFramebufferI3d = ((int)0x2050),
|
||||
DigitalVideoGammaCorrectedI3d = ((int)0x2053),
|
||||
DigitalVideoCursorAlphaValueI3d = ((int)0x2051),
|
||||
DigitalVideoCursorIncludedI3d = ((int)0x2052),
|
||||
}
|
||||
|
||||
public enum WGL_3DFX_multisample
|
||||
{
|
||||
SampleBuffers3dfx = ((int)0x2060),
|
||||
Samples3dfx = ((int)0x2061),
|
||||
}
|
||||
|
||||
public enum WGL_ARB_render_texture
|
||||
{
|
||||
TextureCubeMapPositiveXArb = ((int)0x207d),
|
||||
TextureCubeMapPositiveYArb = ((int)0x207f),
|
||||
Aux0Arb = ((int)0x2087),
|
||||
Texture1dArb = ((int)0x2079),
|
||||
Aux6Arb = ((int)0x208d),
|
||||
TextureCubeMapArb = ((int)0x2078),
|
||||
TextureFormatArb = ((int)0x2072),
|
||||
BackRightArb = ((int)0x2086),
|
||||
BindToTextureRgbArb = ((int)0x2070),
|
||||
MipmapLevelArb = ((int)0x207b),
|
||||
CubeMapFaceArb = ((int)0x207c),
|
||||
TextureCubeMapNegativeXArb = ((int)0x207e),
|
||||
Aux7Arb = ((int)0x208e),
|
||||
Aux8Arb = ((int)0x208f),
|
||||
MipmapTextureArb = ((int)0x2074),
|
||||
NoTextureArb = ((int)0x2077),
|
||||
Aux3Arb = ((int)0x208a),
|
||||
Texture2DArb = ((int)0x207a),
|
||||
Aux1Arb = ((int)0x2088),
|
||||
TextureCubeMapPositiveZArb = ((int)0x2081),
|
||||
BindToTextureRgbaArb = ((int)0x2071),
|
||||
TextureCubeMapNegativeYArb = ((int)0x2080),
|
||||
TextureRgbaArb = ((int)0x2076),
|
||||
FrontRightArb = ((int)0x2084),
|
||||
Aux5Arb = ((int)0x208c),
|
||||
Aux4Arb = ((int)0x208b),
|
||||
TextureTargetArb = ((int)0x2073),
|
||||
FrontLeftArb = ((int)0x2083),
|
||||
Aux9Arb = ((int)0x2090),
|
||||
TextureRgbArb = ((int)0x2075),
|
||||
BackLeftArb = ((int)0x2085),
|
||||
TextureCubeMapNegativeZArb = ((int)0x2082),
|
||||
Aux2Arb = ((int)0x2089),
|
||||
}
|
||||
|
||||
public enum WGL_NV_render_texture_rectangle
|
||||
{
|
||||
BindToTextureRectangleRgbNv = ((int)0x20a0),
|
||||
BindToTextureRectangleRgbaNv = ((int)0x20a1),
|
||||
TextureRectangleNv = ((int)0x20a2),
|
||||
}
|
||||
|
||||
public enum WGL_NV_render_depth_texture
|
||||
{
|
||||
DepthTextureFormatNv = ((int)0x20a5),
|
||||
TextureDepthComponentNv = ((int)0x20a6),
|
||||
BindToTextureDepthNv = ((int)0x20a3),
|
||||
DepthComponentNv = ((int)0x20a7),
|
||||
BindToTextureRectangleDepthNv = ((int)0x20a4),
|
||||
}
|
||||
|
||||
public enum WGL_NV_float_buffer
|
||||
{
|
||||
BindToTextureRectangleFloatRNv = ((int)0x20b1),
|
||||
TextureFloatRNv = ((int)0x20b5),
|
||||
TextureFloatRgbNv = ((int)0x20b7),
|
||||
TextureFloatRgNv = ((int)0x20b6),
|
||||
TextureFloatRgbaNv = ((int)0x20b8),
|
||||
BindToTextureRectangleFloatRgbaNv = ((int)0x20b4),
|
||||
FloatComponentsNv = ((int)0x20b0),
|
||||
BindToTextureRectangleFloatRgNv = ((int)0x20b2),
|
||||
BindToTextureRectangleFloatRgbNv = ((int)0x20b3),
|
||||
}
|
||||
|
||||
public enum WGL_ARB_pixel_format_float
|
||||
{
|
||||
TypeRgbaFloatArb = ((int)0x21a0),
|
||||
}
|
||||
|
||||
public enum WGL_ATI_pixel_format_float
|
||||
{
|
||||
TypeRgbaFloatAti = ((int)0x21a0),
|
||||
}
|
||||
|
||||
public enum WGL_font_type
|
||||
{
|
||||
FontLines = ((int)0),
|
||||
}
|
||||
|
||||
public enum All
|
||||
{
|
||||
SwapCopyExt = ((int)0x2029),
|
||||
BackColorBufferBitArb = ((int)0x00000002),
|
||||
FullAccelerationArb = ((int)0x2027),
|
||||
AccelerationExt = ((int)0x2003),
|
||||
GenlockSourceMultiviewI3d = ((int)0x2044),
|
||||
Aux3Arb = ((int)0x208a),
|
||||
TextureCubeMapNegativeYArb = ((int)0x2080),
|
||||
DoubleBufferArb = ((int)0x2011),
|
||||
SwapUndefinedExt = ((int)0x202a),
|
||||
SupportGdiArb = ((int)0x200f),
|
||||
Aux2Arb = ((int)0x2089),
|
||||
TextureCubeMapArb = ((int)0x2078),
|
||||
SwapLayerBuffersExt = ((int)0x2006),
|
||||
SwapCopyArb = ((int)0x2029),
|
||||
ErrorIncompatibleDeviceContextsArb = ((int)0x2054),
|
||||
TypeColorindexArb = ((int)0x202c),
|
||||
DigitalVideoCursorIncludedI3d = ((int)0x2052),
|
||||
NeedPaletteExt = ((int)0x2004),
|
||||
RedBitsArb = ((int)0x2015),
|
||||
TextureCubeMapNegativeXArb = ((int)0x207e),
|
||||
SampleBuffersExt = ((int)0x2041),
|
||||
GenericAccelerationExt = ((int)0x2026),
|
||||
BindToTextureRectangleRgbaNv = ((int)0x20a1),
|
||||
NoTextureArb = ((int)0x2077),
|
||||
FrontColorBufferBitArb = ((int)0x00000001),
|
||||
TransparentValueExt = ((int)0x200b),
|
||||
AlphaBitsArb = ((int)0x201b),
|
||||
RedBitsExt = ((int)0x2015),
|
||||
PbufferHeightArb = ((int)0x2035),
|
||||
BindToTextureRectangleFloatRgbaNv = ((int)0x20b4),
|
||||
SampleBuffersArb = ((int)0x2041),
|
||||
MipmapLevelArb = ((int)0x207b),
|
||||
NeedSystemPaletteExt = ((int)0x2005),
|
||||
Aux4Arb = ((int)0x208b),
|
||||
TextureFormatArb = ((int)0x2072),
|
||||
AccumBitsExt = ((int)0x201d),
|
||||
AccumBlueBitsExt = ((int)0x2020),
|
||||
BackLeftArb = ((int)0x2085),
|
||||
AlphaBitsExt = ((int)0x201b),
|
||||
StencilBitsArb = ((int)0x2023),
|
||||
DrawToPbufferExt = ((int)0x202d),
|
||||
FullAccelerationExt = ((int)0x2027),
|
||||
ColorBitsExt = ((int)0x2014),
|
||||
BindToTextureRectangleFloatRgNv = ((int)0x20b2),
|
||||
DepthBufferBitArb = ((int)0x00000004),
|
||||
BindToTextureRgbaArb = ((int)0x2071),
|
||||
AccumGreenBitsArb = ((int)0x201f),
|
||||
AccumBitsArb = ((int)0x201d),
|
||||
TypeRgbaFloatArb = ((int)0x21a0),
|
||||
NeedPaletteArb = ((int)0x2004),
|
||||
ShareAccumArb = ((int)0x200e),
|
||||
TransparentArb = ((int)0x200a),
|
||||
ShareStencilArb = ((int)0x200d),
|
||||
Aux5Arb = ((int)0x208c),
|
||||
ImageBufferLockI3d = ((int)0x00000002),
|
||||
TextureFloatRNv = ((int)0x20b5),
|
||||
DepthComponentNv = ((int)0x20a7),
|
||||
FloatComponentsNv = ((int)0x20b0),
|
||||
TransparentGreenValueArb = ((int)0x2038),
|
||||
GenlockSourceExtenalTtlI3d = ((int)0x2047),
|
||||
NeedSystemPaletteArb = ((int)0x2005),
|
||||
BlueBitsExt = ((int)0x2019),
|
||||
GreenShiftExt = ((int)0x2018),
|
||||
OptimalPbufferWidthExt = ((int)0x2031),
|
||||
AuxBuffersExt = ((int)0x2024),
|
||||
TypeRgbaFloatAti = ((int)0x21a0),
|
||||
FrontRightArb = ((int)0x2084),
|
||||
DepthBitsExt = ((int)0x2022),
|
||||
GammaTableSizeI3d = ((int)0x204e),
|
||||
AccumAlphaBitsArb = ((int)0x2021),
|
||||
Aux0Arb = ((int)0x2087),
|
||||
TransparentIndexValueArb = ((int)0x203b),
|
||||
AccumGreenBitsExt = ((int)0x201f),
|
||||
TransparentBlueValueArb = ((int)0x2039),
|
||||
NoAccelerationArb = ((int)0x2025),
|
||||
MaxPbufferPixelsArb = ((int)0x202e),
|
||||
GammaExcludeDesktopI3d = ((int)0x204f),
|
||||
MaxPbufferPixelsExt = ((int)0x202e),
|
||||
AccumBlueBitsArb = ((int)0x2020),
|
||||
SwapUndefinedArb = ((int)0x202a),
|
||||
ShareDepthExt = ((int)0x200c),
|
||||
GenlockSourceEdgeBothI3d = ((int)0x204c),
|
||||
Samples3dfx = ((int)0x2061),
|
||||
DoubleBufferExt = ((int)0x2011),
|
||||
BindToTextureRectangleFloatRgbNv = ((int)0x20b3),
|
||||
SwapMethodExt = ((int)0x2007),
|
||||
ErrorInvalidPixelTypeArb = ((int)0x2043),
|
||||
GreenShiftArb = ((int)0x2018),
|
||||
TextureFloatRgbaNv = ((int)0x20b8),
|
||||
Aux1Arb = ((int)0x2088),
|
||||
GreenBitsArb = ((int)0x2017),
|
||||
NumberPixelFormatsExt = ((int)0x2000),
|
||||
NumberOverlaysExt = ((int)0x2008),
|
||||
PixelTypeArb = ((int)0x2013),
|
||||
SwapLayerBuffersArb = ((int)0x2006),
|
||||
DrawToBitmapArb = ((int)0x2002),
|
||||
NumberPixelFormatsArb = ((int)0x2000),
|
||||
PbufferLostArb = ((int)0x2036),
|
||||
Aux9Arb = ((int)0x2090),
|
||||
TextureCubeMapPositiveZArb = ((int)0x2081),
|
||||
MaxPbufferHeightArb = ((int)0x2030),
|
||||
TransparentExt = ((int)0x200a),
|
||||
PbufferLargestArb = ((int)0x2033),
|
||||
SwapMethodArb = ((int)0x2007),
|
||||
TextureRgbaArb = ((int)0x2076),
|
||||
PbufferWidthExt = ((int)0x2034),
|
||||
OptimalPbufferHeightExt = ((int)0x2032),
|
||||
StencilBitsExt = ((int)0x2023),
|
||||
ShareStencilExt = ((int)0x200d),
|
||||
DepthFloatExt = ((int)0x2040),
|
||||
BindToTextureRgbArb = ((int)0x2070),
|
||||
BindToTextureRectangleRgbNv = ((int)0x20a0),
|
||||
GenlockSourceDigitalSyncI3d = ((int)0x2048),
|
||||
AccumAlphaBitsExt = ((int)0x2021),
|
||||
GenlockSourceExtenalSyncI3d = ((int)0x2045),
|
||||
RedShiftExt = ((int)0x2016),
|
||||
GenlockSourceDigitalFieldI3d = ((int)0x2049),
|
||||
FrontLeftArb = ((int)0x2083),
|
||||
BlueShiftArb = ((int)0x201a),
|
||||
PbufferWidthArb = ((int)0x2034),
|
||||
CubeMapFaceArb = ((int)0x207c),
|
||||
StencilBufferBitArb = ((int)0x00000008),
|
||||
NumberOverlaysArb = ((int)0x2008),
|
||||
SwapExchangeExt = ((int)0x2028),
|
||||
BackRightArb = ((int)0x2086),
|
||||
DepthTextureFormatNv = ((int)0x20a5),
|
||||
TextureFloatRgNv = ((int)0x20b6),
|
||||
Texture1dArb = ((int)0x2079),
|
||||
DepthBitsArb = ((int)0x2022),
|
||||
BindToTextureDepthNv = ((int)0x20a3),
|
||||
DrawToWindowArb = ((int)0x2001),
|
||||
TypeRgbaExt = ((int)0x202b),
|
||||
DigitalVideoCursorAlphaValueI3d = ((int)0x2051),
|
||||
ErrorInvalidPixelTypeExt = ((int)0x2043),
|
||||
AccumRedBitsExt = ((int)0x201e),
|
||||
GreenBitsExt = ((int)0x2017),
|
||||
TypeRgbaArb = ((int)0x202b),
|
||||
DigitalVideoCursorAlphaFramebufferI3d = ((int)0x2050),
|
||||
AuxBuffersArb = ((int)0x2024),
|
||||
AccumRedBitsArb = ((int)0x201e),
|
||||
TextureFloatRgbNv = ((int)0x20b7),
|
||||
TypeColorindexExt = ((int)0x202c),
|
||||
TransparentAlphaValueArb = ((int)0x203a),
|
||||
BlueShiftExt = ((int)0x201a),
|
||||
RedShiftArb = ((int)0x2016),
|
||||
PbufferHeightExt = ((int)0x2035),
|
||||
GenlockSourceEdgeRisingI3d = ((int)0x204b),
|
||||
Texture2DArb = ((int)0x207a),
|
||||
NumberUnderlaysArb = ((int)0x2009),
|
||||
NumberUnderlaysExt = ((int)0x2009),
|
||||
DrawToBitmapExt = ((int)0x2002),
|
||||
ShareDepthArb = ((int)0x200c),
|
||||
TextureDepthComponentNv = ((int)0x20a6),
|
||||
NoAccelerationExt = ((int)0x2025),
|
||||
PixelTypeExt = ((int)0x2013),
|
||||
SupportOpenglArb = ((int)0x2010),
|
||||
TextureCubeMapPositiveYArb = ((int)0x207f),
|
||||
DrawToWindowExt = ((int)0x2001),
|
||||
PbufferLargestExt = ((int)0x2033),
|
||||
DrawToPbufferArb = ((int)0x202d),
|
||||
SupportOpenglExt = ((int)0x2010),
|
||||
SampleBuffers3dfx = ((int)0x2060),
|
||||
GenlockSourceExtenalFieldI3d = ((int)0x2046),
|
||||
MaxPbufferHeightExt = ((int)0x2030),
|
||||
SupportGdiExt = ((int)0x200f),
|
||||
Aux7Arb = ((int)0x208e),
|
||||
DigitalVideoGammaCorrectedI3d = ((int)0x2053),
|
||||
ColorBitsArb = ((int)0x2014),
|
||||
Aux6Arb = ((int)0x208d),
|
||||
ShareAccumExt = ((int)0x200e),
|
||||
StereoArb = ((int)0x2012),
|
||||
TextureRgbArb = ((int)0x2075),
|
||||
AccelerationArb = ((int)0x2003),
|
||||
TextureCubeMapPositiveXArb = ((int)0x207d),
|
||||
TransparentRedValueArb = ((int)0x2037),
|
||||
BlueBitsArb = ((int)0x2019),
|
||||
SwapExchangeArb = ((int)0x2028),
|
||||
SamplesExt = ((int)0x2042),
|
||||
AlphaShiftExt = ((int)0x201c),
|
||||
SamplesArb = ((int)0x2042),
|
||||
TextureTargetArb = ((int)0x2073),
|
||||
BindToTextureRectangleDepthNv = ((int)0x20a4),
|
||||
AlphaShiftArb = ((int)0x201c),
|
||||
Aux8Arb = ((int)0x208f),
|
||||
MaxPbufferWidthExt = ((int)0x202f),
|
||||
GenlockSourceEdgeFallingI3d = ((int)0x204a),
|
||||
StereoExt = ((int)0x2012),
|
||||
MaxPbufferWidthArb = ((int)0x202f),
|
||||
TextureRectangleNv = ((int)0x20a2),
|
||||
ImageBufferMinAccessI3d = ((int)0x00000001),
|
||||
TextureCubeMapNegativeZArb = ((int)0x2082),
|
||||
MipmapTextureArb = ((int)0x2074),
|
||||
GenericAccelerationArb = ((int)0x2026),
|
||||
BindToTextureRectangleFloatRNv = ((int)0x20b1),
|
||||
FontLines = ((int)0),
|
||||
}
|
||||
|
||||
public enum WGL_ARB_extensions_string
|
||||
{
|
||||
}
|
||||
|
||||
public enum WGL_I3D_image_buffer
|
||||
{
|
||||
ImageBufferMinAccessI3d = ((int)0x00000001),
|
||||
ImageBufferLockI3d = ((int)0x00000002),
|
||||
}
|
||||
|
||||
public enum WGL_I3D_swap_frame_lock
|
||||
{
|
||||
}
|
||||
}
|
130
GLWidget/OpenTK/Platform/Windows/WglHelper.cs
Normal file
130
GLWidget/OpenTK/Platform/Windows/WglHelper.cs
Normal file
|
@ -0,0 +1,130 @@
|
|||
/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos
|
||||
* See license.txt for license info
|
||||
*
|
||||
* Date: 12/8/2007
|
||||
* Time: 6:43 <EFBFBD><EFBFBD>
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace OpenTK.Platform.Windows
|
||||
{
|
||||
internal partial class Wgl
|
||||
{
|
||||
private static IntPtr[] EntryPoints;
|
||||
private static string[] EntryPointNames;
|
||||
|
||||
internal const string Library = "OPENGL32.DLL";
|
||||
|
||||
private readonly static Dictionary<string, bool> extensions =
|
||||
new Dictionary<string, bool>();
|
||||
|
||||
private static readonly object sync = new object();
|
||||
|
||||
public Wgl()
|
||||
{
|
||||
}
|
||||
|
||||
public static bool SupportsExtension(string name)
|
||||
{
|
||||
return SupportsExtension(Wgl.GetCurrentDC(), name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a Wgl extension is supported by the given context.
|
||||
/// </summary>
|
||||
/// <param name="dc">The device context.</param>
|
||||
/// <param name="name">The extension to check.</param>
|
||||
/// <returns>True if the extension is supported by the given context, false otherwise</returns>
|
||||
public static bool SupportsExtension(IntPtr dc, string name)
|
||||
{
|
||||
lock (sync)
|
||||
{
|
||||
if (extensions.Count == 0)
|
||||
{
|
||||
// We cache this locally, as another thread might create a context which doesn't support this method.
|
||||
// The design is far from ideal, but there's no good solution to this issue as long as we are using
|
||||
// static WGL/GL classes. Fortunately, this issue is extremely unlikely to arise in practice, as you'd
|
||||
// have to create one accelerated and one non-accelerated context in the same application, with the
|
||||
// non-accelerated context coming second.
|
||||
bool get_arb = SupportsFunction("wglGetExtensionsStringARB");
|
||||
bool get_ext = SupportsFunction("wglGetExtensionsStringEXT");
|
||||
string str =
|
||||
get_arb ? OpenGL.Wgl.GetExtensionsStringARB(dc) :
|
||||
get_ext ? OpenGL.Wgl.GetExtensionsStringEXT():
|
||||
String.Empty;
|
||||
|
||||
if (!String.IsNullOrEmpty(str))
|
||||
{
|
||||
foreach (string ext in str.Split(' '))
|
||||
{
|
||||
extensions.Add(ext, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (extensions.Count > 0)
|
||||
{
|
||||
return extensions.ContainsKey(name);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether an extension function is supported.
|
||||
/// Do not use with core WGL functions, as this function
|
||||
/// will incorrectly return false.
|
||||
/// </summary>
|
||||
/// <param name="name">The extension function to check (e.g. "wglGetExtensionsStringARB"</param>
|
||||
/// <returns>True if the extension function is supported; otherwise, false.</returns>
|
||||
public static bool SupportsFunction(string name)
|
||||
{
|
||||
int index = Array.IndexOf(EntryPointNames, name);
|
||||
if (index >= 0)
|
||||
{
|
||||
return EntryPoints[index] != IntPtr.Zero;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private object SyncRoot
|
||||
{
|
||||
get { return sync; }
|
||||
}
|
||||
|
||||
internal static IntPtr GetAddress(string function_string)
|
||||
{
|
||||
IntPtr address = Wgl.GetProcAddress(function_string);
|
||||
if (!IsValid(address))
|
||||
{
|
||||
address = Functions.GetProcAddress(WinFactory.OpenGLHandle, function_string);
|
||||
}
|
||||
return address;
|
||||
}
|
||||
|
||||
private static bool IsValid(IntPtr address)
|
||||
{
|
||||
// See https://www.opengl.org/wiki/Load_OpenGL_Functions
|
||||
long a = address.ToInt64();
|
||||
bool is_valid = (a < -1) || (a > 3);
|
||||
return is_valid;
|
||||
}
|
||||
|
||||
internal void LoadEntryPoints()
|
||||
{
|
||||
lock (SyncRoot)
|
||||
{
|
||||
if (Wgl.GetCurrentContext() != IntPtr.Zero)
|
||||
{
|
||||
for (int i = 0; i < EntryPointNames.Length; i++)
|
||||
{
|
||||
EntryPoints[i] = GetAddress(EntryPointNames[i]);
|
||||
}
|
||||
extensions.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
200
GLWidget/OpenTK/Platform/Windows/WinDisplayDevice.cs
Normal file
200
GLWidget/OpenTK/Platform/Windows/WinDisplayDevice.cs
Normal file
|
@ -0,0 +1,200 @@
|
|||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2010 the Open Toolkit library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace OpenTK.Platform.Windows
|
||||
{
|
||||
internal sealed class WinDisplayDeviceDriver : DisplayDeviceBase
|
||||
{
|
||||
private readonly object display_lock = new object();
|
||||
|
||||
public WinDisplayDeviceDriver()
|
||||
{
|
||||
RefreshDisplayDevices();
|
||||
SystemEvents.DisplaySettingsChanged +=
|
||||
HandleDisplaySettingsChanged;
|
||||
}
|
||||
|
||||
public sealed override bool TryChangeResolution(DisplayDevice device, DisplayResolution resolution)
|
||||
{
|
||||
DeviceMode mode = null;
|
||||
|
||||
if (resolution != null)
|
||||
{
|
||||
mode = new DeviceMode();
|
||||
mode.PelsWidth = resolution.Width;
|
||||
mode.PelsHeight = resolution.Height;
|
||||
mode.BitsPerPel = resolution.BitsPerPixel;
|
||||
mode.DisplayFrequency = (int)resolution.RefreshRate;
|
||||
mode.Fields = Constants.DM_BITSPERPEL
|
||||
| Constants.DM_PELSWIDTH
|
||||
| Constants.DM_PELSHEIGHT
|
||||
| Constants.DM_DISPLAYFREQUENCY;
|
||||
}
|
||||
|
||||
return Constants.DISP_CHANGE_SUCCESSFUL ==
|
||||
Functions.ChangeDisplaySettingsEx((string)device.Id, mode, IntPtr.Zero,
|
||||
ChangeDisplaySettingsEnum.Fullscreen, IntPtr.Zero);
|
||||
}
|
||||
|
||||
public sealed override bool TryRestoreResolution(DisplayDevice device)
|
||||
{
|
||||
return TryChangeResolution(device, null);
|
||||
}
|
||||
|
||||
public void RefreshDisplayDevices()
|
||||
{
|
||||
lock (display_lock)
|
||||
{
|
||||
// Store an array of the current available DisplayDevice objects.
|
||||
// This is needed to preserve the original resolution.
|
||||
DisplayDevice[] previousDevices = AvailableDevices.ToArray();
|
||||
|
||||
AvailableDevices.Clear();
|
||||
|
||||
// We save all necessary parameters in temporary variables
|
||||
// and construct the device when every needed detail is available.
|
||||
// The main DisplayDevice constructor adds the newly constructed device
|
||||
// to the list of available devices.
|
||||
DisplayDevice opentk_dev;
|
||||
DisplayResolution opentk_dev_current_res = null;
|
||||
List<DisplayResolution> opentk_dev_available_res = new List<DisplayResolution>();
|
||||
bool opentk_dev_primary = false;
|
||||
int device_count = 0, mode_count = 0;
|
||||
|
||||
// Get available video adapters and enumerate all monitors
|
||||
WindowsDisplayDevice dev1 = new WindowsDisplayDevice();
|
||||
while (Functions.EnumDisplayDevices(null, device_count++, dev1, 0))
|
||||
{
|
||||
if ((dev1.StateFlags & DisplayDeviceStateFlags.AttachedToDesktop) == DisplayDeviceStateFlags.None)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
DeviceMode monitor_mode = new DeviceMode();
|
||||
|
||||
// The second function should only be executed when the first one fails
|
||||
// (e.g. when the monitor is disabled)
|
||||
if (Functions.EnumDisplaySettingsEx(dev1.DeviceName.ToString(), DisplayModeSettingsEnum.CurrentSettings, monitor_mode, 0) ||
|
||||
Functions.EnumDisplaySettingsEx(dev1.DeviceName.ToString(), DisplayModeSettingsEnum.RegistrySettings, monitor_mode, 0))
|
||||
{
|
||||
VerifyMode(dev1, monitor_mode);
|
||||
|
||||
float scale = GetScale(ref monitor_mode);
|
||||
opentk_dev_current_res = new DisplayResolution(
|
||||
(int)(monitor_mode.Position.X / scale), (int)(monitor_mode.Position.Y / scale),
|
||||
(int)(monitor_mode.PelsWidth / scale), (int)(monitor_mode.PelsHeight / scale),
|
||||
monitor_mode.BitsPerPel, monitor_mode.DisplayFrequency);
|
||||
|
||||
opentk_dev_primary =
|
||||
(dev1.StateFlags & DisplayDeviceStateFlags.PrimaryDevice) != DisplayDeviceStateFlags.None;
|
||||
}
|
||||
|
||||
opentk_dev_available_res.Clear();
|
||||
mode_count = 0;
|
||||
while (Functions.EnumDisplaySettingsEx(dev1.DeviceName.ToString(), mode_count++, monitor_mode, 0))
|
||||
{
|
||||
VerifyMode(dev1, monitor_mode);
|
||||
|
||||
float scale = GetScale(ref monitor_mode);
|
||||
DisplayResolution res = new DisplayResolution(
|
||||
(int)(monitor_mode.Position.X / scale), (int)(monitor_mode.Position.Y / scale),
|
||||
(int)(monitor_mode.PelsWidth / scale), (int)(monitor_mode.PelsHeight / scale),
|
||||
monitor_mode.BitsPerPel, monitor_mode.DisplayFrequency);
|
||||
|
||||
opentk_dev_available_res.Add(res);
|
||||
}
|
||||
|
||||
// Construct the OpenTK DisplayDevice through the accumulated parameters.
|
||||
// The constructor will automatically add the DisplayDevice to the list
|
||||
// of available devices.
|
||||
#pragma warning disable 612,618
|
||||
opentk_dev = new DisplayDevice(
|
||||
opentk_dev_current_res,
|
||||
opentk_dev_primary,
|
||||
opentk_dev_available_res,
|
||||
opentk_dev_current_res.Bounds,
|
||||
dev1.DeviceName);
|
||||
#pragma warning restore 612,618
|
||||
|
||||
// Set the original resolution if the DisplayDevice was previously available.
|
||||
foreach (DisplayDevice existingDevice in previousDevices)
|
||||
{
|
||||
if ((string)existingDevice.Id == (string)opentk_dev.Id)
|
||||
{
|
||||
opentk_dev.OriginalResolution = existingDevice.OriginalResolution;
|
||||
}
|
||||
}
|
||||
|
||||
AvailableDevices.Add(opentk_dev);
|
||||
|
||||
if (opentk_dev_primary)
|
||||
{
|
||||
Primary = opentk_dev;
|
||||
}
|
||||
|
||||
Debug.Print("DisplayDevice {0} ({1}) supports {2} resolutions.",
|
||||
device_count, opentk_dev.IsPrimary ? "primary" : "secondary", opentk_dev.AvailableResolutions.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private float GetScale(ref DeviceMode monitor_mode)
|
||||
{
|
||||
float scale = 1.0f;
|
||||
if ((monitor_mode.Fields & Constants.DM_LOGPIXELS) != 0)
|
||||
{
|
||||
scale = monitor_mode.LogPixels / 96.0f;
|
||||
}
|
||||
return scale;
|
||||
}
|
||||
|
||||
private static void VerifyMode(WindowsDisplayDevice device, DeviceMode mode)
|
||||
{
|
||||
if (mode.BitsPerPel == 0)
|
||||
{
|
||||
Debug.Print(
|
||||
"[Warning] DisplayDevice '{0}' reported a mode with 0 bpp. Please create a bug report at https://github.com/opentk/opentk/issues",
|
||||
device.DeviceName.ToString());
|
||||
mode.BitsPerPel = 32;
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleDisplaySettingsChanged(object sender, EventArgs e)
|
||||
{
|
||||
RefreshDisplayDevices();
|
||||
}
|
||||
|
||||
~WinDisplayDeviceDriver()
|
||||
{
|
||||
SystemEvents.DisplaySettingsChanged -=
|
||||
HandleDisplaySettingsChanged;
|
||||
}
|
||||
}
|
||||
}
|
109
GLWidget/OpenTK/Platform/Windows/WinFactory.cs
Normal file
109
GLWidget/OpenTK/Platform/Windows/WinFactory.cs
Normal file
|
@ -0,0 +1,109 @@
|
|||
//
|
||||
// The Open Toolkit Library License
|
||||
//
|
||||
// Copyright (c) 2006 - 2009 the Open Toolkit library.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
// OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace OpenTK.Platform.Windows
|
||||
{
|
||||
internal class WinFactory : PlatformFactoryBase
|
||||
{
|
||||
private readonly object SyncRoot = new object();
|
||||
|
||||
// The input drivers must be constructed lazily, *after* the
|
||||
// WinFactory constructor has finished running. The reason is
|
||||
// that they call WinFactory methods internally.
|
||||
internal static IntPtr OpenGLHandle { get; private set; }
|
||||
private const string OpenGLName = "OPENGL32.DLL";
|
||||
|
||||
public WinFactory()
|
||||
{
|
||||
if (System.Environment.OSVersion.Version.Major <= 4)
|
||||
{
|
||||
throw new PlatformNotSupportedException("OpenTK requires Windows XP or higher");
|
||||
}
|
||||
|
||||
// Dynamically load opengl32.dll in order to use the extension loading capabilities of Wgl.
|
||||
// Note: opengl32.dll must be loaded before gdi32.dll, otherwise strange failures may occur
|
||||
// (such as "error: 2000" when calling wglSetPixelFormat or slowness/lag on specific GPUs).
|
||||
LoadOpenGL();
|
||||
|
||||
if (System.Environment.OSVersion.Version.Major >= 6)
|
||||
{
|
||||
if (Toolkit.Options.EnableHighResolution)
|
||||
{
|
||||
// Enable high-dpi support
|
||||
// Only available on Windows Vista and higher
|
||||
bool result = Functions.SetProcessDPIAware();
|
||||
Debug.Print("SetProcessDPIAware() returned {0}", result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void LoadOpenGL()
|
||||
{
|
||||
OpenGLHandle = Functions.LoadLibrary(OpenGLName);
|
||||
if (OpenGLHandle == IntPtr.Zero)
|
||||
{
|
||||
throw new ApplicationException(String.Format("LoadLibrary(\"{0}\") call failed with code {1}",
|
||||
OpenGLName, Marshal.GetLastWin32Error()));
|
||||
}
|
||||
Debug.WriteLine(String.Format("Loaded opengl32.dll: {0}", OpenGLHandle));
|
||||
}
|
||||
|
||||
public override IDisplayDeviceDriver CreateDisplayDeviceDriver()
|
||||
{
|
||||
return new WinDisplayDeviceDriver();
|
||||
}
|
||||
|
||||
public override IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
|
||||
{
|
||||
return new WinGLContext(mode, (WinWindowInfo)window, shareContext, major, minor, flags);
|
||||
}
|
||||
|
||||
public override IGraphicsContext CreateGLContext(ContextHandle handle, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
|
||||
{
|
||||
return new WinGLContext(handle, (WinWindowInfo)window, shareContext, major, minor, flags);
|
||||
}
|
||||
|
||||
public override GraphicsContext.GetCurrentContextDelegate CreateGetCurrentGraphicsContext()
|
||||
{
|
||||
return (GraphicsContext.GetCurrentContextDelegate)delegate
|
||||
{
|
||||
return new ContextHandle(Wgl.GetCurrentContext());
|
||||
};
|
||||
}
|
||||
|
||||
protected override void Dispose(bool manual)
|
||||
{
|
||||
if (!IsDisposed)
|
||||
{
|
||||
base.Dispose(manual);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
455
GLWidget/OpenTK/Platform/Windows/WinGLContext.cs
Normal file
455
GLWidget/OpenTK/Platform/Windows/WinGLContext.cs
Normal file
|
@ -0,0 +1,455 @@
|
|||
/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos
|
||||
* Contributions from Erik Ylvisaker
|
||||
* See license.txt for license info
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Diagnostics;
|
||||
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace OpenTK.Platform.Windows
|
||||
{
|
||||
/// \internal
|
||||
/// <summary>
|
||||
/// Provides methods to create and control an opengl context on the Windows platform.
|
||||
/// This class supports OpenTK, and is not intended for use by OpenTK programs.
|
||||
/// </summary>
|
||||
internal sealed class WinGLContext : DesktopGraphicsContext
|
||||
{
|
||||
private static readonly object LoadLock = new object();
|
||||
|
||||
private bool vsync_supported;
|
||||
private bool vsync_tear_supported;
|
||||
|
||||
private readonly WinGraphicsMode ModeSelector;
|
||||
|
||||
// We need to create a temp context in order to load
|
||||
// wgl extensions (e.g. for multisampling or GL3).
|
||||
// We cannot rely on any WGL extensions before
|
||||
// we load them with the temporary context.
|
||||
private class TemporaryContext : IDisposable
|
||||
{
|
||||
public ContextHandle Context;
|
||||
|
||||
public TemporaryContext(IntPtr native)
|
||||
{
|
||||
Debug.WriteLine("[WGL] Creating temporary context to load extensions");
|
||||
|
||||
if (native == null)
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
// Create temporary context and load WGL entry points
|
||||
// First, set a compatible pixel format to the device context
|
||||
// of the temp window
|
||||
WinWindowInfo window = new WinWindowInfo
|
||||
{
|
||||
Handle = native
|
||||
};
|
||||
WinGraphicsMode selector = new WinGraphicsMode(window.DeviceContext);
|
||||
WinGLContext.SetGraphicsModePFD(selector, GraphicsMode.Default, window);
|
||||
|
||||
bool success = false;
|
||||
|
||||
// Then, construct a temporary context and load all wgl extensions
|
||||
Context = new ContextHandle(Wgl.CreateContext(window.DeviceContext));
|
||||
if (Context != ContextHandle.Zero)
|
||||
{
|
||||
// Make the context current.
|
||||
// Note: on some video cards and on some virtual machines, wglMakeCurrent
|
||||
// may fail with an errorcode of 6 (INVALID_HANDLE). The suggested workaround
|
||||
// is to call wglMakeCurrent in a loop until it succeeds.
|
||||
// See https://www.opengl.org/discussion_boards/showthread.php/171058-nVidia-wglMakeCurrent()-multiple-threads
|
||||
// Sigh...
|
||||
for (int retry = 0; retry < 5 && !success; retry++)
|
||||
{
|
||||
success = Wgl.MakeCurrent(window.DeviceContext, Context.Handle);
|
||||
if (!success)
|
||||
{
|
||||
Debug.Print("wglMakeCurrent failed with error: {0}. Retrying", Marshal.GetLastWin32Error());
|
||||
System.Threading.Thread.Sleep(10);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Print("[WGL] CreateContext failed with error: {0}", Marshal.GetLastWin32Error());
|
||||
}
|
||||
|
||||
if (!success)
|
||||
{
|
||||
Debug.WriteLine("[WGL] Failed to create temporary context");
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (Context != ContextHandle.Zero)
|
||||
{
|
||||
Wgl.MakeCurrent(IntPtr.Zero, IntPtr.Zero);
|
||||
Wgl.DeleteContext(Context.Handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public WinGLContext(GraphicsMode format, WinWindowInfo window, IGraphicsContext sharedContext,
|
||||
int major, int minor, GraphicsContextFlags flags)
|
||||
{
|
||||
// There are many ways this code can break when accessed by multiple threads. The biggest offender is
|
||||
// the sharedContext stuff, which will only become valid *after* this constructor returns.
|
||||
// The easiest solution is to serialize all context construction - hence the big lock, below.
|
||||
lock (LoadLock)
|
||||
{
|
||||
if (window == null)
|
||||
{
|
||||
throw new ArgumentNullException("window", "Must point to a valid window.");
|
||||
}
|
||||
if (window.Handle == IntPtr.Zero)
|
||||
{
|
||||
throw new ArgumentException("window", "Must be a valid window.");
|
||||
}
|
||||
|
||||
IntPtr current_context = Wgl.GetCurrentContext();
|
||||
TemporaryContext temp_context = null;
|
||||
try
|
||||
{
|
||||
if (current_context == IntPtr.Zero)
|
||||
{
|
||||
// Create temporary context to load WGL extensions
|
||||
temp_context = new TemporaryContext(window.Handle);
|
||||
current_context = Wgl.GetCurrentContext();
|
||||
if (current_context != IntPtr.Zero && current_context == temp_context.Context.Handle)
|
||||
{
|
||||
new Wgl().LoadEntryPoints();
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Print("OpenGL will be bound to window:{0} on thread:{1}", window.Handle,
|
||||
System.Threading.Thread.CurrentThread.ManagedThreadId);
|
||||
|
||||
ModeSelector = new WinGraphicsMode(window.DeviceContext);
|
||||
Mode = SetGraphicsModePFD(ModeSelector, format, (WinWindowInfo)window);
|
||||
|
||||
if (Wgl.SupportsFunction("wglCreateContextAttribsARB"))
|
||||
{
|
||||
try
|
||||
{
|
||||
Debug.Write("Using WGL_ARB_create_context... ");
|
||||
|
||||
List<int> attributes = new List<int>();
|
||||
attributes.Add((int)ArbCreateContext.MajorVersion);
|
||||
attributes.Add(major);
|
||||
attributes.Add((int)ArbCreateContext.MinorVersion);
|
||||
attributes.Add(minor);
|
||||
if (flags != 0)
|
||||
{
|
||||
attributes.Add((int)ArbCreateContext.ContextFlags);
|
||||
attributes.Add((int)GetARBContextFlags(flags));
|
||||
attributes.Add((int)ArbCreateContext.ProfileMask);
|
||||
attributes.Add((int)GetARBContextProfile(flags));
|
||||
}
|
||||
// According to the docs, " <attribList> specifies a list of attributes for the context.
|
||||
// The list consists of a sequence of <name,value> pairs terminated by the
|
||||
// value 0. [...]"
|
||||
// Is this a single 0, or a <0, 0> pair? (Defensive coding: add two zeroes just in case).
|
||||
attributes.Add(0);
|
||||
attributes.Add(0);
|
||||
|
||||
Handle = new ContextHandle(
|
||||
OpenGL.Wgl.CreateContextAttribsARB(
|
||||
window.DeviceContext,
|
||||
sharedContext != null ? (sharedContext as IGraphicsContextInternal).Context.Handle : IntPtr.Zero,
|
||||
attributes.ToArray()));
|
||||
if (Handle == ContextHandle.Zero)
|
||||
{
|
||||
Debug.Print("failed. (Error: {0})", Marshal.GetLastWin32Error());
|
||||
}
|
||||
}
|
||||
catch (Exception e) { Debug.Print(e.ToString()); }
|
||||
}
|
||||
|
||||
if (Handle == ContextHandle.Zero)
|
||||
{
|
||||
// Failed to create GL3-level context, fall back to GL2.
|
||||
Debug.Write("Falling back to GL2... ");
|
||||
Handle = new ContextHandle(Wgl.CreateContext(window.DeviceContext));
|
||||
if (Handle == ContextHandle.Zero)
|
||||
{
|
||||
Handle = new ContextHandle(Wgl.CreateContext(window.DeviceContext));
|
||||
}
|
||||
if (Handle == ContextHandle.Zero)
|
||||
{
|
||||
throw new GraphicsContextException(
|
||||
String.Format("Context creation failed. Wgl.CreateContext() error: {0}.",
|
||||
Marshal.GetLastWin32Error()));
|
||||
}
|
||||
}
|
||||
|
||||
Debug.WriteLine(String.Format("success! (id: {0})", Handle));
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (temp_context != null)
|
||||
{
|
||||
temp_context.Dispose();
|
||||
temp_context = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Todo: is this comment still true?
|
||||
// On intel drivers, wgl entry points appear to change
|
||||
// when creating multiple contexts. As a workaround,
|
||||
// we reload Wgl entry points every time we create a
|
||||
// new context - this solves the issue without any apparent
|
||||
// side-effects (i.e. the old contexts can still be handled
|
||||
// using the new entry points.)
|
||||
// Sigh...
|
||||
MakeCurrent(window);
|
||||
new Wgl().LoadEntryPoints();
|
||||
|
||||
if (sharedContext != null)
|
||||
{
|
||||
Marshal.GetLastWin32Error();
|
||||
Debug.Write(String.Format("Sharing state with context {0}: ", sharedContext));
|
||||
bool result = Wgl.ShareLists((sharedContext as IGraphicsContextInternal).Context.Handle, Handle.Handle);
|
||||
Debug.WriteLine(result ? "success!" : "failed with win32 error " + Marshal.GetLastWin32Error());
|
||||
}
|
||||
}
|
||||
|
||||
private static ArbCreateContext GetARBContextFlags(GraphicsContextFlags flags)
|
||||
{
|
||||
ArbCreateContext result = 0;
|
||||
result |= (flags & GraphicsContextFlags.ForwardCompatible) != 0 ?
|
||||
ArbCreateContext.CoreProfileBit : ArbCreateContext.CompatibilityProfileBit;
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ArbCreateContext GetARBContextProfile(GraphicsContextFlags flags)
|
||||
{
|
||||
ArbCreateContext result = 0;
|
||||
result |= (flags & GraphicsContextFlags.Debug) != 0 ? ArbCreateContext.DebugBit : 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
public WinGLContext(ContextHandle handle, WinWindowInfo window, IGraphicsContext sharedContext,
|
||||
int major, int minor, GraphicsContextFlags flags)
|
||||
{
|
||||
if (handle == ContextHandle.Zero)
|
||||
{
|
||||
throw new ArgumentException("handle");
|
||||
}
|
||||
if (window == null)
|
||||
{
|
||||
throw new ArgumentNullException("window");
|
||||
}
|
||||
|
||||
Handle = handle;
|
||||
}
|
||||
|
||||
public override void SwapBuffers()
|
||||
{
|
||||
if (!Functions.SwapBuffers(DeviceContext))
|
||||
{
|
||||
throw new GraphicsContextException(String.Format(
|
||||
"Failed to swap buffers for context {0} current. Error: {1}", this, Marshal.GetLastWin32Error()));
|
||||
}
|
||||
}
|
||||
|
||||
public override void MakeCurrent(IWindowInfo window)
|
||||
{
|
||||
lock (LoadLock)
|
||||
{
|
||||
bool success;
|
||||
|
||||
WinWindowInfo wnd = window as WinWindowInfo;
|
||||
if (wnd != null)
|
||||
{
|
||||
if (wnd.Handle == IntPtr.Zero)
|
||||
{
|
||||
throw new ArgumentException("window", "Must point to a valid window.");
|
||||
}
|
||||
|
||||
success = Wgl.MakeCurrent(wnd.DeviceContext, Handle.Handle);
|
||||
DeviceContext = wnd.DeviceContext;
|
||||
}
|
||||
else
|
||||
{
|
||||
success = Wgl.MakeCurrent(IntPtr.Zero, IntPtr.Zero);
|
||||
DeviceContext = IntPtr.Zero;
|
||||
}
|
||||
|
||||
if (!success)
|
||||
{
|
||||
throw new GraphicsContextException(String.Format(
|
||||
"Failed to make context {0} current. Error: {1}", this, Marshal.GetLastWin32Error()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsCurrent
|
||||
{
|
||||
get { return Wgl.GetCurrentContext() == Handle.Handle; }
|
||||
}
|
||||
|
||||
public override int SwapInterval
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (LoadLock)
|
||||
{
|
||||
if (vsync_supported)
|
||||
{
|
||||
return OpenGL.Wgl.GetSwapIntervalEXT();
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
lock (LoadLock)
|
||||
{
|
||||
if (vsync_supported)
|
||||
{
|
||||
if (value < 0 && !vsync_tear_supported)
|
||||
{
|
||||
value = 1;
|
||||
}
|
||||
if (!OpenGL.Wgl.SwapIntervalEXT(value))
|
||||
{
|
||||
Debug.Print("wglSwapIntervalEXT call failed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void LoadAll()
|
||||
{
|
||||
lock (LoadLock)
|
||||
{
|
||||
new Wgl().LoadEntryPoints();
|
||||
vsync_supported =
|
||||
Wgl.SupportsExtension(DeviceContext, "WGL_EXT_swap_control") &&
|
||||
Wgl.SupportsFunction("wglGetSwapIntervalEXT") &&
|
||||
Wgl.SupportsFunction("wglSwapIntervalEXT");
|
||||
vsync_tear_supported =
|
||||
Wgl.SupportsExtension(DeviceContext, "WGL_EXT_swap_control_tear");
|
||||
}
|
||||
|
||||
base.LoadAll();
|
||||
}
|
||||
/*
|
||||
IWindowInfo IGraphicsContextInternal.Info
|
||||
{
|
||||
get { return (IWindowInfo)windowInfo; }
|
||||
}
|
||||
*/
|
||||
|
||||
public override IntPtr GetAddress(IntPtr function_string)
|
||||
{
|
||||
IntPtr address = Wgl.GetProcAddress(function_string);
|
||||
if (!IsValid(address))
|
||||
{
|
||||
address = Functions.GetProcAddress(WinFactory.OpenGLHandle, function_string);
|
||||
}
|
||||
return address;
|
||||
}
|
||||
|
||||
private static bool IsValid(IntPtr address)
|
||||
{
|
||||
// See https://www.opengl.org/wiki/Load_OpenGL_Functions
|
||||
long a = address.ToInt64();
|
||||
bool is_valid = (a < -1) || (a > 3);
|
||||
return is_valid;
|
||||
}
|
||||
|
||||
// Note: there is no relevant ARB function.
|
||||
internal static GraphicsMode SetGraphicsModePFD(WinGraphicsMode mode_selector,
|
||||
GraphicsMode mode, WinWindowInfo window)
|
||||
{
|
||||
Debug.Write("Setting pixel format... ");
|
||||
if (window == null)
|
||||
{
|
||||
throw new ArgumentNullException("window", "Must point to a valid window.");
|
||||
}
|
||||
|
||||
if (!mode.Index.HasValue)
|
||||
{
|
||||
mode = mode_selector.SelectGraphicsMode(
|
||||
mode.ColorFormat, mode.Depth, mode.Stencil,
|
||||
mode.Samples, mode.AccumulatorFormat,
|
||||
mode.Buffers, mode.Stereo);
|
||||
}
|
||||
|
||||
PixelFormatDescriptor pfd = new PixelFormatDescriptor();
|
||||
Functions.DescribePixelFormat(
|
||||
window.DeviceContext, (int)mode.Index.Value,
|
||||
API.PixelFormatDescriptorSize, ref pfd);
|
||||
|
||||
Debug.WriteLine(mode.Index.ToString());
|
||||
|
||||
if (!Functions.SetPixelFormat(window.DeviceContext, (int)mode.Index.Value, ref pfd))
|
||||
{
|
||||
throw new GraphicsContextException(String.Format(
|
||||
"Requested GraphicsMode not available. SetPixelFormat error: {0}",
|
||||
Marshal.GetLastWin32Error()));
|
||||
}
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
internal IntPtr DeviceContext { get; private set; }
|
||||
|
||||
/// <summary>Returns a System.String describing this OpenGL context.</summary>
|
||||
/// <returns>A System.String describing this OpenGL context.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return (this as IGraphicsContextInternal).Context.ToString();
|
||||
}
|
||||
|
||||
protected override void Dispose(bool calledManually)
|
||||
{
|
||||
if (!IsDisposed)
|
||||
{
|
||||
if (calledManually)
|
||||
{
|
||||
DestroyContext();
|
||||
}
|
||||
IsDisposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void DestroyContext()
|
||||
{
|
||||
if (Handle != ContextHandle.Zero)
|
||||
{
|
||||
try
|
||||
{
|
||||
// This will fail if the user calls Dispose() on thread X when the context is current on thread Y.
|
||||
if (!Wgl.DeleteContext(Handle.Handle))
|
||||
{
|
||||
Debug.Print("Failed to destroy OpenGL context {0}. Error: {1}",
|
||||
Handle.ToString(), Marshal.GetLastWin32Error());
|
||||
}
|
||||
}
|
||||
catch (AccessViolationException e)
|
||||
{
|
||||
Debug.WriteLine("An access violation occured while destroying the OpenGL context. Please report at https://github.com/opentk/opentk/issues");
|
||||
Debug.Indent();
|
||||
Debug.Print("Marshal.GetLastWin32Error(): {0}", Marshal.GetLastWin32Error().ToString());
|
||||
Debug.WriteLine(e.ToString());
|
||||
Debug.Unindent();
|
||||
}
|
||||
Handle = ContextHandle.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue