diff --git a/appveyor.yml b/appveyor.yml index 92796ce4..28f1f89c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,3 +1,4 @@ +image: Visual Studio 2017 init: - git config --global core.autocrlf input build_script: diff --git a/build.fsx b/build.fsx index b153c0fb..530bb12a 100644 --- a/build.fsx +++ b/build.fsx @@ -105,7 +105,8 @@ Target "AssemblyInfo" (fun _ -> Attribute.Version release.AssemblyVersion Attribute.FileVersion release.AssemblyVersion Attribute.CLSCompliant true - Attribute.Copyright copyright ] + Attribute.Copyright copyright + ] let getProjectDetails projectPath = let projectName = System.IO.Path.GetFileNameWithoutExtension(projectPath) diff --git a/src/OpenTK.GLWidget/GLWidget.cs b/src/OpenTK.GLWidget/GLWidget.cs index 5abababc..49e45f90 100644 --- a/src/OpenTK.GLWidget/GLWidget.cs +++ b/src/OpenTK.GLWidget/GLWidget.cs @@ -1,14 +1,9 @@ using System; using System.Threading; using System.ComponentModel; - +using Gdk; using OpenTK.Graphics; -using OpenTK.Platform; - using Gtk; -using OpenTK.OSX; -using OpenTK.Win; -using OpenTK.X11; namespace OpenTK { @@ -17,66 +12,28 @@ namespace OpenTK /// [CLSCompliant(false)] [ToolboxItem(true)] - public class GLWidget: DrawingArea + public class GLWidget : GLArea { - private static int _GraphicsContextCount; private static bool _SharedContextInitialized = false; private IGraphicsContext _GraphicsContext; - private IWindowInfo _WindowInfo; private bool _Initialized = false; /// - /// Use a single buffer versus a double buffer. + /// The previous frame time reported by GTK. /// - [Browsable(true)] - public bool SingleBuffer { get; set; } + private double? _PreviousFrameTime; /// - /// Color Buffer Bits-Per-Pixel + /// Gets the time taken to render the last frame (in seconds). /// - public int ColorBPP { get; set; } + public double DeltaTime { get; private set; } /// - /// Accumulation Buffer Bits-Per-Pixel + /// The set for this widget. /// - public int AccumulatorBPP { get; set; } - - /// - /// Depth Buffer Bits-Per-Pixel - /// - public int DepthBPP { get; set; } - - /// - /// Stencil Buffer Bits-Per-Pixel - /// - public int StencilBPP { get; set; } - - /// - /// Number of samples - /// - public int Samples { get; set; } - - /// - /// Indicates if steropic renderering is enabled - /// - public bool Stereo { get; set; } - - /// - /// The major version of OpenGL to use. - /// - public int GlVersionMajor { get; set; } - - /// - /// The minor version of OpenGL to use. - /// - public int GlVersionMinor { get; set; } - - /// - /// The set for this widget. - /// - public GraphicsContextFlags GraphicsContextFlags { get; set; } + public GraphicsContextFlags ContextFlags { get; } /// /// Initializes a new instance of the class. @@ -98,24 +55,71 @@ namespace OpenTK /// The which the widget should be constructed with. /// The major OpenGL version to attempt to initialize. /// The minor OpenGL version to attempt to initialize. - /// + /// /// Any flags which should be used during initialization of the . /// - public GLWidget(GraphicsMode graphicsMode, int glVersionMajor, int glVersionMinor, GraphicsContextFlags graphicsContextFlags) + public GLWidget(GraphicsMode graphicsMode, int glVersionMajor, int glVersionMinor, GraphicsContextFlags contextFlags) { - this.DoubleBuffered = false; + ContextFlags = contextFlags; - SingleBuffer = graphicsMode.Buffers == 1; - ColorBPP = graphicsMode.ColorFormat.BitsPerPixel; - AccumulatorBPP = graphicsMode.AccumulatorFormat.BitsPerPixel; - DepthBPP = graphicsMode.Depth; - StencilBPP = graphicsMode.Stencil; - Samples = graphicsMode.Samples; - Stereo = graphicsMode.Stereo; + AddTickCallback(UpdateFrameTime); + SetRequiredVersion(glVersionMajor, glVersionMinor); - GlVersionMajor = glVersionMajor; - GlVersionMinor = glVersionMinor; - GraphicsContextFlags = graphicsContextFlags; + if (graphicsMode.Depth > 0) + { + HasDepthBuffer = true; + } + + if (graphicsMode.Stencil > 0) + { + HasStencilBuffer = true; + } + + if (graphicsMode.ColorFormat.Alpha > 0) + { + HasAlpha = true; + } + } + + /// + /// Updates the time delta with a new value from the last frame. + /// + /// The sending widget. + /// The relevant frame clock. + /// true if the callback should be called again; otherwise, false. + private bool UpdateFrameTime(Widget widget, FrameClock frameClock) + { + var frameTimeµSeconds = frameClock.FrameTime; + + if (!_PreviousFrameTime.HasValue) + { + _PreviousFrameTime = frameTimeµSeconds; + + return true; + } + + var frameTimeSeconds = (frameTimeµSeconds - _PreviousFrameTime) / 10e6; + + DeltaTime = (float)frameTimeSeconds; + _PreviousFrameTime = frameTimeµSeconds; + + return true; + } + + + /// + protected override GLContext OnCreateContext() + { + var gdkGLContext = Window.CreateGlContext(); + + GetRequiredVersion(out var major, out var minor); + gdkGLContext.SetRequiredVersion(major, minor); + + gdkGLContext.DebugEnabled = ContextFlags.HasFlag(GraphicsContextFlags.Debug); + gdkGLContext.ForwardCompatible = ContextFlags.HasFlag(GraphicsContextFlags.ForwardCompatible); + + gdkGLContext.Realize(); + return gdkGLContext; } /// @@ -137,39 +141,15 @@ namespace OpenTK base.Destroy(); } -#if !GTK3 - /// - /// Disposes the current object, releasing any native resources it was using. - /// - /// - public override void Dispose() - { - GC.SuppressFinalize(this); - Dispose(true); - - base.Dispose(); - } -#endif - -#if GTK3 /// /// Disposes the current object, releasing any native resources it was using. /// /// protected override void Dispose(bool disposing) { - base.Dispose(disposing); -#else - /// - /// Disposes the current object, releasing any native resources it was using. - /// - /// - public virtual void Dispose(bool disposing) - { -#endif if (disposing) { - _GraphicsContext.MakeCurrent(_WindowInfo); + MakeCurrent(); OnShuttingDown(); if (GraphicsContext.ShareContexts && (Interlocked.Decrement(ref _GraphicsContextCount) == 0)) { @@ -231,22 +211,6 @@ namespace OpenTK } } - /// - /// Called when this needs to render a frame. - /// - public event EventHandler RenderFrame; - - /// - /// Invokes the event. - /// - protected virtual void OnRenderFrame() - { - if (RenderFrame != null) - { - RenderFrame(this, EventArgs.Empty); - } - } - /// /// Called when this is being disposed. /// @@ -263,62 +227,19 @@ namespace OpenTK } } -#if GTK3 /// /// Called when the widget needs to be (fully or partially) redrawn. /// /// /// protected override bool OnDrawn(Cairo.Context cr) -#else - /// - /// Called when the widget is exposed. - /// - /// - /// - protected override bool OnExposeEvent(Gdk.EventExpose evnt) -#endif { if (!_Initialized) { Initialize(); } - else - { - _GraphicsContext.MakeCurrent(_WindowInfo); - } -#if GTK3 var result = base.OnDrawn(cr); -#else - bool result = base.OnExposeEvent(evnt); -#endif - - OnRenderFrame(); - -#if !GTK3 - evnt.Window.Display.Sync(); // Add Sync call to fix resize rendering problem (Jay L. T. Cornwall) - How does this affect VSync? -#endif - - _GraphicsContext.SwapBuffers(); - - return result; - } - - /// - /// Called whenever the widget is resized. - /// - /// - /// - protected override bool OnConfigureEvent(Gdk.EventConfigure evnt) - { - bool result = base.OnConfigureEvent(evnt); - - if (_GraphicsContext != null) - { - _GraphicsContext.Update(_WindowInfo); - } - return result; } @@ -329,66 +250,17 @@ namespace OpenTK { _Initialized = true; - // If this looks uninitialized... initialize. - if (ColorBPP == 0) + // Make the GDK GL context current + MakeCurrent(); + + // Create a dummy context that will grab the GdkGLContext that is current on the thread + _GraphicsContext = new GraphicsContext(ContextHandle.Zero, null); + + if (ContextFlags.HasFlag(GraphicsContextFlags.Debug)) { - ColorBPP = 32; - - if (DepthBPP == 0) - { - DepthBPP = 16; - } + _GraphicsContext.ErrorChecking = true; } - ColorFormat colorBufferColorFormat = new ColorFormat(ColorBPP); - - ColorFormat accumulationColorFormat = new ColorFormat(AccumulatorBPP); - - int buffers = 2; - if (SingleBuffer) - { - buffers--; - } - - GraphicsMode graphicsMode = new GraphicsMode(colorBufferColorFormat, DepthBPP, StencilBPP, Samples, accumulationColorFormat, buffers, Stereo); - - if (Configuration.RunningOnWindows) - { - Console.WriteLine("OpenTK running on windows"); - } - else if (Configuration.RunningOnMacOS) - { - Console.WriteLine("OpenTK running on OSX"); - } - else - { - Console.WriteLine("OpenTK running on X11"); - } - -#if GTK3 - IntPtr widgetWindowHandle = this.Window.Handle; -#else - IntPtr widgetWindowHandle = this.GdkWindow.Handle; -#endif - - // IWindowInfo - if (Configuration.RunningOnWindows) - { - _WindowInfo = WinWindowsInfoInitializer.Initialize(widgetWindowHandle); - } - else if (Configuration.RunningOnMacOS) - { - _WindowInfo = OSXWindowInfoInitializer.Initialize(widgetWindowHandle); - } - else - { - _WindowInfo = XWindowInfoInitializer.Initialize(graphicsMode, this.Display.Handle, this.Screen.Number, widgetWindowHandle, this.Screen.RootWindow.Handle); - } - - // GraphicsContext - _GraphicsContext = new GraphicsContext(graphicsMode, _WindowInfo, GlVersionMajor, GlVersionMinor, GraphicsContextFlags); - _GraphicsContext.MakeCurrent(_WindowInfo); - if (GraphicsContext.ShareContexts) { Interlocked.Increment(ref _GraphicsContextCount); diff --git a/src/OpenTK.GLWidget/OSX/OSXWindowInfoInitializer.cs b/src/OpenTK.GLWidget/OSX/OSXWindowInfoInitializer.cs deleted file mode 100644 index cfdba748..00000000 --- a/src/OpenTK.GLWidget/OSX/OSXWindowInfoInitializer.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using System.Runtime.InteropServices; -using System.Security; -using OpenTK.Platform; - -namespace OpenTK.OSX -{ - /// - /// Handler class for initializing objects under the OSX platform for both GTK2 and - /// GTK3. - /// - public static class OSXWindowInfoInitializer - { -#if GTK3 - private const string OSXLibGdkName = "libgdk-3.dylib"; -#else - const string OSXLibGdkName = "libgdk-quartz-2.0.0.dylib"; -#endif - - /// - /// Initializes an under the OSX platform. - /// - /// - public static IWindowInfo Initialize(IntPtr gdkWindowHandle) - { - IntPtr windowHandle = gdk_quartz_window_get_nswindow(gdkWindowHandle); - IntPtr viewHandle = gdk_quartz_window_get_nsview(gdkWindowHandle); - - return Utilities.CreateMacOSWindowInfo(windowHandle, viewHandle); - } - - [SuppressUnmanagedCodeSecurity, DllImport(OSXLibGdkName)] - private static extern IntPtr gdk_quartz_window_get_nswindow(IntPtr handle); - - [SuppressUnmanagedCodeSecurity, DllImport(OSXLibGdkName)] - private static extern IntPtr gdk_quartz_window_get_nsview(IntPtr handle); - } -} \ No newline at end of file diff --git a/src/OpenTK.GLWidget/OpenTK.GLWidget.csproj b/src/OpenTK.GLWidget/OpenTK.GLWidget.csproj index 6e771eba..c82f52bd 100644 --- a/src/OpenTK.GLWidget/OpenTK.GLWidget.csproj +++ b/src/OpenTK.GLWidget/OpenTK.GLWidget.csproj @@ -42,7 +42,7 @@ v4.5 true - 6 + 7 true ..\..\stylecop.ruleset @@ -98,13 +98,10 @@ - Code - - @@ -120,8 +117,7 @@ - + ..\..\packages\gtk-sharp3\lib\net40\cairo-sharp.dll diff --git a/src/OpenTK.GLWidget/Win/WinWindowsInfoInitializer.cs b/src/OpenTK.GLWidget/Win/WinWindowsInfoInitializer.cs deleted file mode 100644 index 95303104..00000000 --- a/src/OpenTK.GLWidget/Win/WinWindowsInfoInitializer.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using System.Runtime.InteropServices; -using System.Security; -using OpenTK.Platform; - -namespace OpenTK.Win -{ - /// - /// Handler class for initializing objects under the Windows platform for both GTK2 and - /// GTK3. - /// - public static class WinWindowsInfoInitializer - { -#if GTK3 - private const string WinLibGDKName = "libgdk-3-0.dll"; -#else - private const string WinLibGDKName = "libgdk-win32-2.0-0.dll"; -#endif - - /// - /// Initializes an under the Windows platform. - /// - /// - public static IWindowInfo Initialize(IntPtr gdkWindowHandle) - { -#if GTK3 - IntPtr windowHandle = gdk_win32_window_get_handle(gdkWindowHandle); -#else - IntPtr windowHandle = gdk_win32_drawable_get_handle(gdkWindowHandle); -#endif - return Utilities.CreateWindowsWindowInfo(windowHandle); - } - -#if GTK3 - [SuppressUnmanagedCodeSecurity, DllImport(WinLibGDKName, CallingConvention = CallingConvention.Cdecl)] - private static extern IntPtr gdk_win32_window_get_handle(IntPtr w); -#else - [SuppressUnmanagedCodeSecurity, DllImport(WinLibGDKName, CallingConvention = CallingConvention.Cdecl)] - static extern IntPtr gdk_win32_drawable_get_handle(IntPtr d); -#endif - - } -} \ No newline at end of file diff --git a/src/OpenTK.GLWidget/X11/XWindowInfoInitializer.cs b/src/OpenTK.GLWidget/X11/XWindowInfoInitializer.cs deleted file mode 100644 index 74b86d54..00000000 --- a/src/OpenTK.GLWidget/X11/XWindowInfoInitializer.cs +++ /dev/null @@ -1,175 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; -using System.Security; -using OpenTK.Graphics; -using OpenTK.Platform; -using OpenTK.Platform.X11; - -namespace OpenTK.X11 -{ - /// - /// Handler class for initializing objects under the X11 platform for both GTK2 and GTK3. - /// - public static class XWindowInfoInitializer - { - -#if GTK3 - private const string UnixLibGdkName = "libgdk-3.so.0"; -#else - const string UnixLibGdkName = "libgdk-x11-2.0.so.0"; -#endif - private const string UnixLibX11Name = "libX11.so.6"; - private const string UnixLibGLName = "libGL.so.1"; - - /// - /// Initializes an under the X11 platform. - /// - /// - /// - /// - /// - /// - /// - public static IWindowInfo Initialize(GraphicsMode mode, IntPtr displayHandle, int screenNumber, IntPtr gdkWindowHandle, IntPtr gdkRootWindowHandle) - { - IntPtr display = gdk_x11_display_get_xdisplay(displayHandle); - -#if GTK3 - IntPtr windowXid = gdk_x11_window_get_xid(gdkWindowHandle); - IntPtr rootWindowXid = gdk_x11_window_get_xid(gdkRootWindowHandle); -#else - IntPtr windowXid = gdk_x11_drawable_get_xid(gdkWindowHandle); - IntPtr rootWindowXid = gdk_x11_drawable_get_xid(gdkRootWindowHandle); -#endif - - IntPtr visualInfo; - if (mode.Index.HasValue) - { - XVisualInfo info = new XVisualInfo - { - VisualID = mode.Index.Value - }; - - int dummy; - visualInfo = XGetVisualInfo(display, XVisualInfoMask.ID, ref info, out dummy); - } - else - { - visualInfo = GetVisualInfo(mode, display, screenNumber); - } - - IWindowInfo retval = Utilities.CreateX11WindowInfo(display, screenNumber, windowXid, rootWindowXid, visualInfo); - XFree(visualInfo); - - return retval; - } - - private static IntPtr XGetVisualInfo(IntPtr display, XVisualInfoMask infoMask, ref XVisualInfo template, out int nitems) - { - return XGetVisualInfoInternal(display, (IntPtr)(int)infoMask, ref template, out nitems); - } - - private static IntPtr GetVisualInfo(GraphicsMode mode, IntPtr display, int screenNumber) - { - try - { - int[] attributes = CreateAttributeList(mode).ToArray(); - return glXChooseVisual(display, screenNumber, 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 static List CreateAttributeList(GraphicsMode mode) - { - List attributeList = new List(24); - - attributeList.Add((int)GLXAttribute.RGBA); - - if (mode.Buffers > 1) - { - attributeList.Add((int)GLXAttribute.DOUBLEBUFFER); - } - - if (mode.Stereo) - { - attributeList.Add((int)GLXAttribute.STEREO); - } - - attributeList.Add((int)GLXAttribute.RED_SIZE); - attributeList.Add(mode.ColorFormat.Red / 4); // TODO support 16-bit - - attributeList.Add((int)GLXAttribute.GREEN_SIZE); - attributeList.Add(mode.ColorFormat.Green / 4); // TODO support 16-bit - - attributeList.Add((int)GLXAttribute.BLUE_SIZE); - attributeList.Add(mode.ColorFormat.Blue / 4); // TODO support 16-bit - - attributeList.Add((int)GLXAttribute.ALPHA_SIZE); - attributeList.Add(mode.ColorFormat.Alpha / 4); // TODO support 16-bit - - attributeList.Add((int)GLXAttribute.DEPTH_SIZE); - attributeList.Add(mode.Depth); - - attributeList.Add((int)GLXAttribute.STENCIL_SIZE); - attributeList.Add(mode.Stencil); - - //attributeList.Add(GLX_AUX_BUFFERS); - //attributeList.Add(Buffers); - - attributeList.Add((int)GLXAttribute.ACCUM_RED_SIZE); - attributeList.Add(mode.AccumulatorFormat.Red / 4); // TODO support 16-bit - - attributeList.Add((int)GLXAttribute.ACCUM_GREEN_SIZE); - attributeList.Add(mode.AccumulatorFormat.Green / 4); // TODO support 16-bit - - attributeList.Add((int)GLXAttribute.ACCUM_BLUE_SIZE); - attributeList.Add(mode.AccumulatorFormat.Blue / 4); // TODO support 16-bit - - attributeList.Add((int)GLXAttribute.ACCUM_ALPHA_SIZE); - attributeList.Add(mode.AccumulatorFormat.Alpha / 4); // TODO support 16-bit - - attributeList.Add((int)GLXAttribute.NONE); - - return attributeList; - } - - [DllImport(UnixLibX11Name, EntryPoint = "XGetVisualInfo")] - private static extern IntPtr XGetVisualInfoInternal(IntPtr display, IntPtr infoMask, ref XVisualInfo template, out int nitems); - - [SuppressUnmanagedCodeSecurity, DllImport(UnixLibX11Name)] - private static extern void XFree(IntPtr handle); - -#if GTK3 - /// Returns the X resource (window or pixmap) belonging to a GdkWindow. - /// XID gdk_x11_window_get_xid(GdkWindow *drawable); - /// The GdkDrawable. - /// The ID of window's X resource. - [SuppressUnmanagedCodeSecurity, DllImport(UnixLibGdkName)] - private static extern IntPtr gdk_x11_window_get_xid(IntPtr gdkDisplay); -#else - /// Returns the X resource (window or pixmap) belonging to a GdkDrawable. - /// XID gdk_x11_drawable_get_xid(GdkDrawable *drawable); - /// The GdkDrawable. - /// The ID of drawable's X resource. - [SuppressUnmanagedCodeSecurity, DllImport(UnixLibGdkName)] - static extern IntPtr gdk_x11_drawable_get_xid(IntPtr gdkDisplay); -#endif - /// Returns the X display of a GdkDisplay. - /// Display* gdk_x11_display_get_xdisplay(GdkDisplay *display); - /// The GdkDrawable. - /// The X Display of the GdkDisplay. - [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); - } -} \ No newline at end of file diff --git a/src/OpenTK/Properties/AssemblyInfo.cs b/src/OpenTK/Properties/AssemblyInfo.cs index f0d6b897..045ffa41 100644 --- a/src/OpenTK/Properties/AssemblyInfo.cs +++ b/src/OpenTK/Properties/AssemblyInfo.cs @@ -1,6 +1,7 @@ // using System; using System.Reflection; +using System.Runtime.CompilerServices; [assembly: AssemblyTitleAttribute("OpenTK")] [assembly: AssemblyProductAttribute("OpenTK")] @@ -9,6 +10,7 @@ using System.Reflection; [assembly: AssemblyFileVersionAttribute("3.0.0")] [assembly: CLSCompliantAttribute(true)] [assembly: AssemblyCopyrightAttribute("Copyright (c) 2006 - 2016 Stefanos Apostolopoulos for the Open Toolkit library.")] +[assembly: InternalsVisibleToAttribute("OpenTK.GLWidget, PublicKey=0024000004800000940000000602000000240000525341310004000011000000a3e05aafb87f71fb8fd02b512707f289c12341de98c6ce2ec1494b71c20cb2032cbd65d091b447df3ec772257efb9fa3591201937890e067da1d29a339948a12b29c2847a787cc9fbef2a3bf78267026e85f36aab827228df4bb580e3ae0599ade036f0a97a0e6982f5406d98d114455f332350f6d8369db655e9c3e7976c2c8")] namespace System { internal static class AssemblyVersionInformation { internal const System.String AssemblyTitle = "OpenTK"; @@ -18,5 +20,6 @@ namespace System { internal const System.String AssemblyFileVersion = "3.0.0"; internal const System.Boolean CLSCompliant = true; internal const System.String AssemblyCopyright = "Copyright (c) 2006 - 2016 Stefanos Apostolopoulos for the Open Toolkit library."; + internal const System.String InternalsVisibleTo = "OpenTK.GLWidget, PublicKey=0024000004800000940000000602000000240000525341310004000011000000a3e05aafb87f71fb8fd02b512707f289c12341de98c6ce2ec1494b71c20cb2032cbd65d091b447df3ec772257efb9fa3591201937890e067da1d29a339948a12b29c2847a787cc9fbef2a3bf78267026e85f36aab827228df4bb580e3ae0599ade036f0a97a0e6982f5406d98d114455f332350f6d8369db655e9c3e7976c2c8"; } }