From 1af25f540caf82250f01375c4425604546129cd0 Mon Sep 17 00:00:00 2001 From: cra0zy Date: Sat, 5 Dec 2015 23:39:37 +0100 Subject: [PATCH 1/8] GLWidget for Gtk 2 and 3 --- OpenTK.sln | 28 +- Source/Examples/OpenTK.Examples.csproj | 19 +- .../OpenTK/GLWidget/GLWidgetSimple.cs | 152 +++++ Source/GLWidget/GLWidget.cs | 575 ++++++++++++++++++ Source/GLWidget/OpenTK.GLWidget.csproj | 174 ++++++ Source/GLWidget/Properties/AssemblyInfo.cs | 15 + 6 files changed, 955 insertions(+), 8 deletions(-) create mode 100644 Source/Examples/OpenTK/GLWidget/GLWidgetSimple.cs create mode 100644 Source/GLWidget/GLWidget.cs create mode 100644 Source/GLWidget/OpenTK.GLWidget.csproj create mode 100644 Source/GLWidget/Properties/AssemblyInfo.cs diff --git a/OpenTK.sln b/OpenTK.sln index dd6eeedf..16749266 100644 --- a/OpenTK.sln +++ b/OpenTK.sln @@ -1,5 +1,6 @@ + Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2012 +# Visual Studio 2010 VisualStudioVersion = 12.0.21005.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTK", "Source\OpenTK\OpenTK.csproj", "{A37A7E14-0000-0000-0000-000000000000}" @@ -79,6 +80,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.API.Desktop", "Source\ {75DC22B1-113F-4A66-96B9-2FF8208C10E8} = {75DC22B1-113F-4A66-96B9-2FF8208C10E8} EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTK.GLWidget", "Source\GLWidget\OpenTK.GLWidget.csproj", "{A625BE87-0000-0000-0000-000000000000}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -158,15 +161,30 @@ Global {A37A7E14-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU {A37A7E14-0000-0000-0000-000000000000}.ReleaseMinimal|Any CPU.ActiveCfg = ReleaseMinimal|Any CPU {A37A7E14-0000-0000-0000-000000000000}.ReleaseMinimal|Any CPU.Build.0 = ReleaseMinimal|Any CPU + {A625BE87-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A625BE87-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A625BE87-0000-0000-0000-000000000000}.DebugMinimal|Any CPU.ActiveCfg = DebugMinimal|Any CPU + {A625BE87-0000-0000-0000-000000000000}.DebugMinimal|Any CPU.Build.0 = DebugMinimal|Any CPU + {A625BE87-0000-0000-0000-000000000000}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU + {A625BE87-0000-0000-0000-000000000000}.Documentation|Any CPU.Build.0 = Documentation|Any CPU + {A625BE87-0000-0000-0000-000000000000}.Nsis|Any CPU.ActiveCfg = Nsis|Any CPU + {A625BE87-0000-0000-0000-000000000000}.Nsis|Any CPU.Build.0 = Nsis|Any CPU + {A625BE87-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A625BE87-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU + {A625BE87-0000-0000-0000-000000000000}.ReleaseMinimal|Any CPU.ActiveCfg = ReleaseMinimal|Any CPU + {A625BE87-0000-0000-0000-000000000000}.ReleaseMinimal|Any CPU.Build.0 = ReleaseMinimal|Any CPU {A625BE88-0000-0000-0000-000000000000}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A625BE88-0000-0000-0000-000000000000}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A625BE88-0000-0000-0000-000000000000}.DebugMinimal|Any CPU.ActiveCfg = Debug|Any CPU + {A625BE88-0000-0000-0000-000000000000}.DebugMinimal|Any CPU.ActiveCfg = DebugMinimal|Any CPU + {A625BE88-0000-0000-0000-000000000000}.DebugMinimal|Any CPU.Build.0 = DebugMinimal|Any CPU {A625BE88-0000-0000-0000-000000000000}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU + {A625BE88-0000-0000-0000-000000000000}.Documentation|Any CPU.Build.0 = Documentation|Any CPU {A625BE88-0000-0000-0000-000000000000}.Nsis|Any CPU.ActiveCfg = Nsis|Any CPU {A625BE88-0000-0000-0000-000000000000}.Nsis|Any CPU.Build.0 = Nsis|Any CPU {A625BE88-0000-0000-0000-000000000000}.Release|Any CPU.ActiveCfg = Release|Any CPU {A625BE88-0000-0000-0000-000000000000}.Release|Any CPU.Build.0 = Release|Any CPU {A625BE88-0000-0000-0000-000000000000}.ReleaseMinimal|Any CPU.ActiveCfg = ReleaseMinimal|Any CPU + {A625BE88-0000-0000-0000-000000000000}.ReleaseMinimal|Any CPU.Build.0 = ReleaseMinimal|Any CPU {ADC34399-7613-44D2-90B2-19250F06FE7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {ADC34399-7613-44D2-90B2-19250F06FE7A}.DebugMinimal|Any CPU.ActiveCfg = DebugMinimal|Any CPU {ADC34399-7613-44D2-90B2-19250F06FE7A}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU @@ -210,10 +228,10 @@ Global {C4DDD20F-CB4E-43F4-A75C-4A3D668E1F99}.Release|Any CPU.Build.0 = Release|Any CPU {C4DDD20F-CB4E-43F4-A75C-4A3D668E1F99}.ReleaseMinimal|Any CPU.ActiveCfg = ReleaseMinimal|Any CPU EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection GlobalSection(MonoDevelopProperties) = preSolution StartupItem = Source\Examples\OpenTK.Examples.csproj EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection EndGlobal diff --git a/Source/Examples/OpenTK.Examples.csproj b/Source/Examples/OpenTK.Examples.csproj index 9a3f2fd6..68cf447d 100644 --- a/Source/Examples/OpenTK.Examples.csproj +++ b/Source/Examples/OpenTK.Examples.csproj @@ -2,7 +2,7 @@ Local - 8.0.50727 + 8.0.30703 2.0 {868E37B3-0000-0000-0000-000000000000} Debug @@ -15,7 +15,6 @@ Grid IE50 false - v2.0 WinExe @@ -81,6 +80,7 @@ 4 True TRACE; + true True @@ -122,6 +122,11 @@ System.Xml + + + + + @@ -129,8 +134,12 @@ {A37A7E14-0000-0000-0000-000000000000} - OpenTK.GLControl {A625BE88-0000-0000-0000-000000000000} + OpenTK.GLControl + + + {A625BE87-0000-0000-0000-000000000000} + OpenTK.GLWidget @@ -564,6 +573,7 @@ + @@ -672,4 +682,7 @@ + + + \ No newline at end of file diff --git a/Source/Examples/OpenTK/GLWidget/GLWidgetSimple.cs b/Source/Examples/OpenTK/GLWidget/GLWidgetSimple.cs new file mode 100644 index 00000000..0cbc2b6a --- /dev/null +++ b/Source/Examples/OpenTK/GLWidget/GLWidgetSimple.cs @@ -0,0 +1,152 @@ +// This code was written for the OpenTK library and has been released +// to the Public Domain. +// It is provided "as is" without express or implied warranty of any kind. + +using System; +using System.Drawing; +using System.Threading; + +using Gtk; + +using OpenTK; +using OpenTK.Graphics; +using OpenTK.Graphics.OpenGL; + +namespace Examples.GLWidget +{ + [Example("GLWidget Simple", ExampleCategory.OpenTK, "GLWidget", 1, Documentation="GLWidgetSimple")] + public class SimpleWindow : Window + { + VBox vbox1; + HBox hbox1; + Button button_red, button_green, button_blue; + OpenTK.GLWidget glwidget1; + + public SimpleWindow() + : base(WindowType.Toplevel) + { + Build(); + } + + private void Build() + { + this.Title = "Sample GLWidget Example"; + this.DefaultWidth = 800; + this.DefaultHeight = 600; + + vbox1 = new VBox(); + + glwidget1 = new OpenTK.GLWidget(); + glwidget1.Initialized += Glwidget1_Initialized; + + // do note that if you are placing the widget inside a container you have to do it after initalization + var t = new Thread(new ThreadStart(delegate { + Thread.Sleep(50); + + Application.Invoke(delegate { + vbox1.PackStart(glwidget1, true, true, 1); + glwidget1.Show(); + }); + })); + t.Start(); + + hbox1 = new HBox(); + + button_blue = new Button("Clear Blue"); + button_blue.Clicked += Button_blue_Clicked; + hbox1.PackStart(button_blue, true, true, 0); + + button_green = new Button("Clear Green"); + button_green.Clicked += Button_green_Clicked; + hbox1.PackStart(button_green, true, true, 1); + + button_red = new Button("Clear Red"); + button_red.Clicked += Button_red_Clicked; + hbox1.PackStart(button_red, true, true, 2); + + vbox1.PackStart(hbox1, false, false, 0); + + this.Add(vbox1); + this.ShowAll(); + + this.DeleteEvent += OnDeleteEvent; + } + + #region Events + + protected void Glwidget1_Initialized(object sender, EventArgs e) + { + GL.ClearColor(1.0f, 1.0f, 1.0f, 1.0f); + + GL.MatrixMode(MatrixMode.Projection); + GL.LoadIdentity(); + GL.Ortho(-1.0, 1.0, -1.0, 1.0, 0.0, 4.0); + + glwidget1.SizeAllocated += Glwidget1_SizeAllocated; + glwidget1.RenderFrame += Glwidget1_RenderFrame; + } + + protected void Glwidget1_SizeAllocated(object o, SizeAllocatedArgs args) + { + GL.Viewport(0, 0, args.Allocation.Width, args.Allocation.Height); + } + + protected void Glwidget1_RenderFrame(object sender, EventArgs e) + { + GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); + + GL.Begin(PrimitiveType.Triangles); + + GL.Color3(Color.MidnightBlue); + GL.Vertex2(-1.0f, 1.0f); + GL.Color3(Color.SpringGreen); + GL.Vertex2(0.0f, -1.0f); + GL.Color3(Color.Ivory); + GL.Vertex2(1.0f, 1.0f); + + GL.End(); + + GraphicsContext.CurrentContext.SwapBuffers(); + } + + protected void Button_blue_Clicked(object sender, EventArgs e) + { + GL.ClearColor(Color.RoyalBlue); + glwidget1.QueueDraw(); + } + + protected void Button_green_Clicked(object sender, EventArgs e) + { + GL.ClearColor(Color.ForestGreen); + glwidget1.QueueDraw(); + } + + protected void Button_red_Clicked(object sender, EventArgs e) + { + GL.ClearColor(Color.Crimson); + glwidget1.QueueDraw(); + } + + protected void OnDeleteEvent(object sender, DeleteEventArgs a) + { + Application.Quit(); + a.RetVal = true; + } + + #endregion + + #region public static void Main() + + public static void Main(string[] args) + { + Application.Init(); + + SimpleWindow win = new SimpleWindow(); + win.Show(); + + Application.Run(); + } + + #endregion + } +} diff --git a/Source/GLWidget/GLWidget.cs b/Source/GLWidget/GLWidget.cs new file mode 100644 index 00000000..92274a30 --- /dev/null +++ b/Source/GLWidget/GLWidget.cs @@ -0,0 +1,575 @@ +#region License +// +// The Open Toolkit Library License +// +// Copyright (c) 2006 - 2009 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. +// +#endregion + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Security; +using System.Threading; +using System.ComponentModel; + +using OpenTK.Graphics; +using OpenTK.Platform; +using OpenTK; + +using Gtk; + +namespace OpenTK +{ + [ToolboxItem(true)] + public class GLWidget: DrawingArea, IDisposable + { + + #region Static attrs. + + static int _GraphicsContextCount; + static bool _SharedContextInitialized = false; + + #endregion + + #region Attributes + + IGraphicsContext _GraphicsContext; + IWindowInfo _WindowInfo; + GraphicsContextFlags _GraphicsContextFlags; + bool _Initialized = false; + + #endregion + + #region Properties + + /// Use a single buffer versus a double buffer. + [Browsable(true)] + public bool SingleBuffer { get; set; } + + /// Color Buffer Bits-Per-Pixel + public int ColorBPP { get; set; } + + /// Accumulation Buffer Bits-Per-Pixel + 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; } + + public GraphicsContextFlags GraphicsContextFlags + { + get + { + return _GraphicsContextFlags; + } + set + { + _GraphicsContextFlags = value; + } + } + + #endregion + + #region Construction/Destruction + + /// Constructs a new GLWidget. + public GLWidget() + : this(GraphicsMode.Default) + { + } + + /// Constructs a new GLWidget using a given GraphicsMode + public GLWidget(GraphicsMode graphicsMode) + : this(graphicsMode, 1, 0, GraphicsContextFlags.Default) + { + } + + /// Constructs a new GLWidget + public GLWidget(GraphicsMode graphicsMode, int glVersionMajor, int glVersionMinor, GraphicsContextFlags graphicsContextFlags) + { + this.DoubleBuffered = false; + + SingleBuffer = graphicsMode.Buffers == 1; + ColorBPP = graphicsMode.ColorFormat.BitsPerPixel; + AccumulatorBPP = graphicsMode.AccumulatorFormat.BitsPerPixel; + DepthBPP = graphicsMode.Depth; + StencilBPP = graphicsMode.Stencil; + Samples = graphicsMode.Samples; + Stereo = graphicsMode.Stereo; + + GlVersionMajor = glVersionMajor; + GlVersionMinor = glVersionMinor; + GraphicsContextFlags = graphicsContextFlags; + } + + ~GLWidget() + { + Dispose(false); + } + +#if GTK3 + public override void Destroy() { +#else + public override void Dispose() + { +#endif + GC.SuppressFinalize(this); + Dispose(true); +#if GTK3 + base.Destroy(); +#else + base.Dispose(); +#endif + } + + public virtual void Dispose(bool disposing) + { + if (disposing) + { + _GraphicsContext.MakeCurrent(_WindowInfo); + OnShuttingDown(); + if (GraphicsContext.ShareContexts && (Interlocked.Decrement(ref _GraphicsContextCount) == 0)) + { + OnGraphicsContextShuttingDown(); + _SharedContextInitialized = false; + } + _GraphicsContext.Dispose(); + } + } + + #endregion + + #region New Events + + // Called when the first GraphicsContext is created in the case of GraphicsContext.ShareContexts == True; + public static event EventHandler GraphicsContextInitialized; + + 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; + + 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() + { + if (RenderFrame != null) + RenderFrame(this, EventArgs.Empty); + } + + // Called when this GLWidget is being Disposed + public event EventHandler ShuttingDown; + + protected virtual void OnShuttingDown() + { + if (ShuttingDown != null) + ShuttingDown(this, EventArgs.Empty); + } + + #endregion + + // 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. +#if GTK3 + protected override bool OnDrawn(Cairo.Context cr) +#else + 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 on Resize + protected override bool OnConfigureEvent(Gdk.EventConfigure evnt) + { + bool result = base.OnConfigureEvent(evnt); + + if (_GraphicsContext != null) + _GraphicsContext.Update(_WindowInfo); + + return result; + } + + void Initialize() + { + _Initialized = true; + + // If this looks uninitialized... initialize. + if (ColorBPP == 0) + { + ColorBPP = 32; + + if (DepthBPP == 0) + DepthBPP = 16; + } + + 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"); + + // IWindowInfo + if (Configuration.RunningOnWindows) + _WindowInfo = InitializeWindows(); + else if (Configuration.RunningOnMacOS) + _WindowInfo = InitializeOSX(); + else + _WindowInfo = InitializeX(graphicsMode); + + // GraphicsContext + _GraphicsContext = new GraphicsContext(graphicsMode, _WindowInfo, GlVersionMajor, GlVersionMinor, _GraphicsContextFlags); + _GraphicsContext.MakeCurrent(_WindowInfo); + + if (GraphicsContext.ShareContexts) + { + Interlocked.Increment(ref _GraphicsContextCount); + + if (!_SharedContextInitialized) + { + _SharedContextInitialized = true; + ((IGraphicsContextInternal)_GraphicsContext).LoadAll(); + OnGraphicsContextInitialized(); + } + } + else + { + ((IGraphicsContextInternal)_GraphicsContext).LoadAll(); + OnGraphicsContextInitialized(); + } + + OnInitialized(); + } + + #region Windows Specific initalization + + IWindowInfo InitializeWindows() + { + IntPtr windowHandle = gdk_win32_drawable_get_handle(GdkWindow.Handle); + return Utilities.CreateWindowsWindowInfo(windowHandle); + } + + [SuppressUnmanagedCodeSecurity, DllImport("libgdk-win32-2.0-0.dll")] + public static extern IntPtr gdk_win32_drawable_get_handle(IntPtr d); + + #endregion + + #region OSX Specific Initialization + + IWindowInfo InitializeOSX() + { + IntPtr windowHandle = gdk_quartz_window_get_nswindow(this.GdkWindow.Handle); + IntPtr viewHandle = gdk_quartz_window_get_nsview(this.GdkWindow.Handle); + return Utilities.CreateMacOSWindowInfo(windowHandle, viewHandle); + } + + [SuppressUnmanagedCodeSecurity, DllImport("libgdk-quartz-2.0.0.dylib")] + static extern IntPtr gdk_quartz_window_get_nswindow(IntPtr handle); + + [SuppressUnmanagedCodeSecurity, DllImport("libgdk-quartz-2.0.0.dylib")] + static extern IntPtr gdk_quartz_window_get_nsview(IntPtr handle); + + #endregion + + #region X Specific Initialization + +#if GTK3 + const string UnixLibGdkName = "libgdk-3.so.0"; +#else + const string UnixLibGdkName = "libgdk-x11-2.0.so.0"; +#endif + 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 String.Format("id ({0}), screen ({1}), depth ({2}), class ({3})", + VisualID, Screen, Depth, 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, + } + + IWindowInfo InitializeX(GraphicsMode mode) + { + IntPtr display = gdk_x11_display_get_xdisplay(Display.Handle); + int screen = Screen.Number; +#if GTK3 + IntPtr windowHandle = gdk_x11_window_get_xid(GdkWindow.Handle); + IntPtr rootWindow = gdk_x11_window_get_xid(RootWindow.Handle); +#else + IntPtr windowHandle = gdk_x11_drawable_get_xid(GdkWindow.Handle); + IntPtr rootWindow = gdk_x11_drawable_get_xid(RootWindow.Handle); +#endif + IWindowInfo retval; + + 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); + + retval = Utilities.CreateX11WindowInfo(display, screen, windowHandle, rootWindow, visualInfo); + XFree(visualInfo); + + return retval; + } + + 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); + } + + 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); + } + } + + List AttributeList + { + get + { + List attributeList = new List(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_AUX_BUFFERS); + //attributeList.Add(Buffers); + + 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; + } + } + + [DllImport(UnixLibX11Name, EntryPoint = "XGetVisualInfo")] + static extern IntPtr XGetVisualInfoInternal(IntPtr display, IntPtr vinfo_mask, ref XVisualInfo template, out int nitems); + + [SuppressUnmanagedCodeSecurity, DllImport(UnixLibX11Name)] + static extern void XFree(IntPtr handle); + + /// 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); + + /// 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_window_get_xid(IntPtr gdkDisplay); + + /// 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)] + static extern IntPtr gdk_x11_display_get_xdisplay(IntPtr gdkDisplay); + + [SuppressUnmanagedCodeSecurity, DllImport(UnixLibGLName)] + static extern IntPtr glXChooseVisual(IntPtr display, int screen, int[] attr); + + #endregion + + } + +} diff --git a/Source/GLWidget/OpenTK.GLWidget.csproj b/Source/GLWidget/OpenTK.GLWidget.csproj new file mode 100644 index 00000000..10eb34bc --- /dev/null +++ b/Source/GLWidget/OpenTK.GLWidget.csproj @@ -0,0 +1,174 @@ + + + + Local + 8.0.30703 + 2.0 + {A625BE87-0000-0000-0000-000000000000} + Debug + AnyCPU + + + OpenTK.GLWidget + JScript + Grid + IE50 + false + Library + + + OpenTK.GLWidget + + + + + 2.0 + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + True + 285212672 + + + DEBUG;TRACE; + ..\..\Binaries\OpenTK\Debug\OpenTK.GLWidget.xml + True + 4096 + False + ..\..\Binaries\OpenTK\Debug\ + False + False + 4 + AllRules.ruleset + full + + + True + 285212672 + + + TRACE; + ..\..\Binaries\OpenTK\Release\OpenTK.GLWidget.xml + 4096 + True + ..\..\Binaries\OpenTK\Release\ + False + False + 4 + AllRules.ruleset + none + + + ..\..\Binaries\OpenTK\Release\ + none + 4 + True + TRACE; + true + ..\..\Binaries\OpenTK\Release\OpenTK.GLWidget.xml + + + True + 285212672 + + + TRACE; + ..\..\Binaries\OpenTK\Release\OpenTK.GLWidget.xml + 4096 + True + ..\..\Binaries\OpenTK\Release\ + False + False + 4 + AllRules.ruleset + none + + + True + + + ..\..\OpenTK.snk + + + + System + + + + + + + + + + + OpenTK + {A37A7E14-0000-0000-0000-000000000000} + False + + + + + Properties\GlobalAssemblyInfo.cs + + + Code + + + + + + + + + + + + true + full + false + ..\..\Binaries\OpenTK\Debug\ + DEBUG;TRACE; + 4 + ..\..\Binaries\OpenTK\Debug\OpenTK.GLWidget.xml + AllRules.ruleset + true + False + 285212672 + + + False + 4096 + + + none + true + ..\..\Binaries\OpenTK\Release\ + TRACE; + 4 + ..\..\Binaries\OpenTK\Release\OpenTK.GLWidget.xml + AllRules.ruleset + true + False + 285212672 + + + False + 4096 + + diff --git a/Source/GLWidget/Properties/AssemblyInfo.cs b/Source/GLWidget/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..09db0733 --- /dev/null +++ b/Source/GLWidget/Properties/AssemblyInfo.cs @@ -0,0 +1,15 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OpenTK.GLWidget")] +[assembly: AssemblyDescription("Provides integration with Gtk 2 and 3.")] + +[assembly: System.CLSCompliant(true)] +[assembly: System.Security.AllowPartiallyTrustedCallers] +#if NET40 +[assembly: System.Security.SecurityRules(System.Security.SecurityRuleSet.Level1)] +#endif From 32b0c8e98544100160c728ce376578632ecd43f4 Mon Sep 17 00:00:00 2001 From: Thomas Altenburger Date: Fri, 8 Jan 2016 11:43:05 +0100 Subject: [PATCH 2/8] Fix PS4 controller mapping on Windows --- Source/OpenTK/Input/GamePadConfigurationDatabase.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Source/OpenTK/Input/GamePadConfigurationDatabase.cs b/Source/OpenTK/Input/GamePadConfigurationDatabase.cs index cbd503de..86cce259 100644 --- a/Source/OpenTK/Input/GamePadConfigurationDatabase.cs +++ b/Source/OpenTK/Input/GamePadConfigurationDatabase.cs @@ -76,6 +76,8 @@ namespace OpenTK.Input // Windows - XInput Add("78696e70757400000000000000000000,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,"); + // Windows - XInput (SDL2) + Add("78696e70757401000000000000000000,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,"); // Windows Add("341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,"); @@ -88,7 +90,8 @@ namespace OpenTK.Input Add("4c056802000000000000504944564944,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,"); Add("25090500000000000000504944564944,PS3 DualShock,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b0,y:b3,"); Add("4c05c405000000000000504944564944,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,"); - + Add("05c4054c000000000000504944564944,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a5,rightx:a2,righty:a3,start:b9,x:b0,y:b3,"); + // Mac OS X Add("0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,"); Add("6d0400000000000016c2000000000000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,"); // Guide button doesn't seem to be sent in DInput mode. From 8488bb6229ea88f3546c2c45c5edb6134e429c9d Mon Sep 17 00:00:00 2001 From: Thomas Altenburger Date: Fri, 8 Jan 2016 11:43:39 +0100 Subject: [PATCH 3/8] Fix HID WinRaw driver to handle PS4 controller --- Source/OpenTK/Platform/Windows/WinRawJoystick.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Source/OpenTK/Platform/Windows/WinRawJoystick.cs b/Source/OpenTK/Platform/Windows/WinRawJoystick.cs index 9357dd9c..455dfe52 100644 --- a/Source/OpenTK/Platform/Windows/WinRawJoystick.cs +++ b/Source/OpenTK/Platform/Windows/WinRawJoystick.cs @@ -81,8 +81,11 @@ namespace OpenTK.Platform.Windows public void SetAxis(short collection, HIDPage page, short usage, short value) { - JoystickAxis axis = GetAxis(collection, page, usage); - State.SetAxis(axis, value); + if (page == HIDPage.GenericDesktop || page == HIDPage.Simulation) // set axis only when HIDPage is known by HidHelper.TranslateJoystickAxis() to avoid axis0 to be overwritten by unknown HIDPage + { + JoystickAxis axis = GetAxis(collection, page, usage); + State.SetAxis(axis, value); + } } public void SetButton(short collection, HIDPage page, short usage, bool value) @@ -351,6 +354,12 @@ namespace OpenTK.Platform.Windows { if (caps.LogicalMax == 8) return (HatPosition)value; + else if (caps.LogicalMax == 7) + { + value++; + value %= 9; + return (HatPosition)value; + } else return HatPosition.Centered; } From b29bc2f5347a3d4407a1fb4e4275ad889474d8fc Mon Sep 17 00:00:00 2001 From: Thomas Altenburger Date: Fri, 8 Jan 2016 13:16:38 +0100 Subject: [PATCH 4/8] Fixes keyboard being recognized as 2 HID devices --- Source/OpenTK/Platform/Windows/WinRawJoystick.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Source/OpenTK/Platform/Windows/WinRawJoystick.cs b/Source/OpenTK/Platform/Windows/WinRawJoystick.cs index 455dfe52..82f13c60 100644 --- a/Source/OpenTK/Platform/Windows/WinRawJoystick.cs +++ b/Source/OpenTK/Platform/Windows/WinRawJoystick.cs @@ -261,7 +261,7 @@ namespace OpenTK.Platform.Windows // This is a new device, query its capabilities and add it // to the device list - if (!QueryDeviceCaps(device)) + if (!QueryDeviceCaps(device) && !is_xinput) { continue; } @@ -611,6 +611,8 @@ namespace OpenTK.Platform.Windows } } } + else + return false; } finally { From 2e51fe019771f4c70b15bb25b3a560f712a45fbf Mon Sep 17 00:00:00 2001 From: Fraser Waters Date: Mon, 18 Jan 2016 19:17:31 +0000 Subject: [PATCH 5/8] Notice of leave --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index d07d7342..e4cebf7d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,12 @@ +Notice +====== + +@frassle (current maintainer) is stepping away from this project. The project owner is not around to give direction, and I don't have access to the website, nuget account, travis account or most permissions on the github account. I can't push this project forward. + +As I'm the only one whos maintained this repo for the last 6 months with my absence pull requests and issues will probably stay unresolved. I'd suggest developer look to other projects like [MonoGame](http://www.monogame.net/) or [SDL2#](https://github.com/flibitijibibo/SDL2-CS). + +As this is a large project used by many people I thought it best to add this notice before signing off. + OpenTK ====== From bbbeb98438982b906c0500ac60726c1e2846c2bc Mon Sep 17 00:00:00 2001 From: cra0zy Date: Tue, 16 Feb 2016 18:00:42 +0100 Subject: [PATCH 6/8] Remove notice of leave --- README.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/README.md b/README.md index e4cebf7d..d07d7342 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,3 @@ -Notice -====== - -@frassle (current maintainer) is stepping away from this project. The project owner is not around to give direction, and I don't have access to the website, nuget account, travis account or most permissions on the github account. I can't push this project forward. - -As I'm the only one whos maintained this repo for the last 6 months with my absence pull requests and issues will probably stay unresolved. I'd suggest developer look to other projects like [MonoGame](http://www.monogame.net/) or [SDL2#](https://github.com/flibitijibibo/SDL2-CS). - -As this is a large project used by many people I thought it best to add this notice before signing off. - OpenTK ====== From 470be54933047eac4136b56372ea1f0d508b9869 Mon Sep 17 00:00:00 2001 From: The Gitter Badger Date: Thu, 18 Feb 2016 10:51:10 +0000 Subject: [PATCH 7/8] Add Gitter badge --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index d07d7342..ce743ee0 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ OpenTK ====== +[![Join the chat at https://gitter.im/opentk/opentk](https://badges.gitter.im/opentk/opentk.svg)](https://gitter.im/opentk/opentk?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + The Open Toolkit library is a fast, low-level C# binding for OpenGL, OpenGL ES and OpenAL. It runs on all major platforms and powers hundreds of apps, games and scientific research. Use OpenTK to add cross-platform 3d graphics, audio, compute and haptics to your C# application. Integrate it into your existing user interface or use it standalone without any external dependencies. From b944d92754de8cd5b32fc9c91347f929290d4513 Mon Sep 17 00:00:00 2001 From: cra0zy Date: Fri, 19 Feb 2016 18:03:11 +0100 Subject: [PATCH 8/8] [Linux X11] Fix incorrect window state if it was set while the window was invisible --- Source/OpenTK/Platform/X11/X11GLNative.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Source/OpenTK/Platform/X11/X11GLNative.cs b/Source/OpenTK/Platform/X11/X11GLNative.cs index 46099c3e..8cbb25d5 100644 --- a/Source/OpenTK/Platform/X11/X11GLNative.cs +++ b/Source/OpenTK/Platform/X11/X11GLNative.cs @@ -116,6 +116,7 @@ namespace OpenTK.Platform.X11 // back, reset window to these.s WindowBorder _previous_window_border; Size _previous_window_size; + OpenTK.WindowState _previous_window_state = OpenTK.WindowState.Normal; MouseCursor cursor = MouseCursor.Default; IntPtr cursorHandle; @@ -1281,6 +1282,8 @@ namespace OpenTK.Platform.X11 // ProcessEvents. ChangeWindowState(value); ProcessEvents(); + + _previous_window_state = (value == OpenTK.WindowState.Fullscreen) ? OpenTK.WindowState.Fullscreen : OpenTK.WindowState.Normal; } } @@ -1611,6 +1614,8 @@ namespace OpenTK.Platform.X11 { Functions.XMapWindow(window.Display, window.Handle); } + + this.WindowState = _previous_window_state; } else if (!value && visible) { @@ -1618,6 +1623,8 @@ namespace OpenTK.Platform.X11 { Functions.XUnmapWindow(window.Display, window.Handle); } + + _previous_window_state = (this.WindowState == OpenTK.WindowState.Fullscreen) ? OpenTK.WindowState.Fullscreen : OpenTK.WindowState.Normal; } } }