From 1af25f540caf82250f01375c4425604546129cd0 Mon Sep 17 00:00:00 2001 From: cra0zy Date: Sat, 5 Dec 2015 23:39:37 +0100 Subject: [PATCH] GLWidget for Gtk 2 and 3 --- OpenTK.sln | 28 +- Source/Examples/OpenTK.Examples.csproj | 19 +- Source/Examples/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 dd6eeed..1674926 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 9a3f2fd..68cf447 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 0000000..0cbc2b6 --- /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 0000000..92274a3 --- /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 0000000..10eb34b --- /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 0000000..09db073 --- /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 -- 2.7.4