diff --git a/Source/OpenTK/GLControl.Designer.cs b/Source/OpenTK/GLControl.Designer.cs
index 8ef3fc05..8a009a78 100644
--- a/Source/OpenTK/GLControl.Designer.cs
+++ b/Source/OpenTK/GLControl.Designer.cs
@@ -1,6 +1,4 @@
-using System;
-
-namespace OpenTK
+namespace OpenTK
{
partial class GLControl
{
@@ -32,12 +30,12 @@ namespace OpenTK
{
this.SuspendLayout();
//
- // GLControl
+ // NewGLControl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.Black;
- this.Name = "GLControl";
+ this.Name = "NewGLControl";
this.ResumeLayout(false);
}
diff --git a/Source/OpenTK/GLControl.cs b/Source/OpenTK/GLControl.cs
index 3869c4dc..7379ff6d 100644
--- a/Source/OpenTK/GLControl.cs
+++ b/Source/OpenTK/GLControl.cs
@@ -4,115 +4,140 @@
*/
#endregion
-#region --- Using Directives ---
-
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
+using System.Data;
using System.Text;
using System.Windows.Forms;
-using System.Diagnostics;
using OpenTK.Platform;
-using OpenTK.OpenGL;
-
-#endregion
namespace OpenTK
{
- // TODO: Document the GLControl class.
-
///
- /// Defines a UserControl with opengl rendering capabilities.
+ /// Defines a UserControl with OpenGL rendering capabilities.
///
- public partial class GLControl : UserControl, IGLControl
+ public partial class GLControl : UserControl
{
- #region --- Private Fields ---
+ IGLContext context;
+ IPlatformIdle idle;
- private IGLControl glControl;
+ #region --- Constructor ---
- #endregion
-
- #region --- Contructors ---
-
- ///
- /// Constructs a new GLControl.
- ///
public GLControl()
- :this(new DisplayMode())
- {
- }
-
- ///
- /// Constructs a new GLControl, with the specified DisplayMode.
- ///
- /// The DisplayMode of the control.
- public GLControl(DisplayMode mode)
{
InitializeComponent();
- this.Visible = false;
- this.Fullscreen = mode.Fullscreen;
-
this.SetStyle(ControlStyles.UserPaint, true);
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
- //this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
}
#endregion
+ #region --- Context Setup ---
+
+ protected override void OnHandleCreated(EventArgs e)
+ {
+ base.OnHandleCreated(e);
+
+ // For maximum compatibility we do not set a specific depth for the DisplayMode.
+ // The driver is free to find the best match.
+ WindowInfo info = new WindowInfo(this);
+ if (!this.DesignMode)
+ {
+ context = new GLContext(new DisplayMode(), info);
+ context.CreateContext();
+ idle = new PlatformIdle(info);
+ }
+ else
+ {
+ context = new DummyGLContext();
+ idle = new DummyPlatformIdle();
+ }
+ }
+
+ protected override void OnHandleDestroyed(EventArgs e)
+ {
+ base.OnHandleDestroyed(e);
+
+ context.Dispose();
+ }
+
+ #endregion
+
+ #region --- Public Properties ---
+
+ #region public bool IsIdle
+
+ ///
+ /// Gets a value indicating whether the current thread contains pending system messages.
+ ///
+ public bool IsIdle
+ {
+ get { return idle.IsIdle; }
+ }
+
+ #endregion
+
+ #region public IGLContext Context
+
+ ///
+ /// Gets an interface to the underlying GLContext used by this GLControl.
+ ///
+ public IGLContext Context
+ {
+ get { return context; }
+ }
+
+ #endregion
+
+ #region public float AspectRatio
+
+ ///
+ /// Gets the aspect ratio of this GLControl.
+ ///
+ public float AspectRatio
+ {
+ get
+ {
+ return this.ClientSize.Width / (float)this.ClientSize.Height;
+ }
+ }
+
+ #endregion
+
+ #region public bool VSync
+
+ ///
+ /// Gets or sets a value indicating whether vsync is active for this GLControl.
+ ///
+ public bool VSync
+ {
+ get
+ {
+ if (Context != null)
+ return Context.VSync;
+ return false;
+ }
+ set
+ {
+ if (Context != null)
+ Context.VSync = value;
+ }
+ }
+
+ #endregion
+
+ #endregion
+
#region --- Public Methods ---
- #region public void CreateContext()
-
- ///
- /// Forces the creation of the opengl rendering context.
- ///
- public void CreateContext()
- {
- if (glControl != null)
- {
- throw new ApplicationException("Attempted to create GLControl more than once.");
- }
-
- if (this.DesignMode)
- {
- glControl = new DummyGLControl();
- }
- else
- {
- switch (Environment.OSVersion.Platform)
- {
- case PlatformID.Win32NT:
- case PlatformID.Win32Windows:
- glControl = new OpenTK.Platform.Windows.WinGLControl(this, new DisplayMode(Width, Height));
- break;
-
- case PlatformID.Unix:
- case (PlatformID)128: // some older versions of Mono reported 128.
- glControl = new OpenTK.Platform.X11.X11GLControl(this);
- break;
-
- default:
- throw new PlatformNotSupportedException("Your operating system is not currently supported. We are sorry for the inconvenience.");
- }
- }
-
- this.Visible = true;
- this.CreateControl();
-
- GL.LoadAll();
- Glu.LoadAll();
- this.OnResize(EventArgs.Empty);
- }
-
- #endregion
-
#region public void SwapBuffers()
///
- /// Swaps the front and back buffers, and presents the rendered scene to the screen.
+ /// Swaps the front and back buffers, presenting the rendered scene to the screen.
///
public void SwapBuffers()
{
@@ -124,8 +149,8 @@ namespace OpenTK
#region public void MakeCurrent()
///
- /// Makes the underlying GLContext of this GLControl current. All OpenGL commands issued
- /// from this point are interpreted by this GLContext.
+ /// Makes the underlying this GLControl current in the calling thread.
+ /// All OpenGL commands issued are hereafter interpreted by this GLControl.
///
public void MakeCurrent()
{
@@ -135,147 +160,114 @@ namespace OpenTK
#endregion
#endregion
+ }
- #region --- Public Properties ---
+ #region internal interface IPlatformIdle
- ///
- /// Gets the AspectRatio of the control this GLContext object
- /// renders to. This is usually used in a call to Glu.Perspective.
- ///
- public double AspectRatio
+ internal interface IPlatformIdle
+ {
+ bool IsIdle { get; }
+ }
+
+ internal class WinPlatformIdle : IPlatformIdle
+ {
+ OpenTK.Platform.Windows.MSG msg = new OpenTK.Platform.Windows.MSG();
+ object get_lock = new object();
+ IntPtr handle;
+
+ public WinPlatformIdle(IWindowInfo info)
{
- get
- {
- return this.Width / (double)this.Height;
- }
+ handle = info.Handle;
}
- ///
- /// Gets or sets the display mode of the control.
- ///
- public bool Fullscreen
+ #region IPlatformIdle Members
+
+ public bool IsIdle
{
- get
+ get
{
- return false;
- //throw new NotImplementedException();
- }
- set
- {
- //throw new NotImplementedException();
+ lock (get_lock)
+ {
+ return !OpenTK.Platform.Windows.Functions.PeekMessage(ref msg, IntPtr.Zero, 0, 0, 0);
+ }
}
}
#endregion
+ }
- #region --- IGLControl Members ---
+ internal class X11PlatformIdle : IPlatformIdle
+ {
+ object get_lock = new object();
+ IntPtr display;
- #region public bool IsIdle
+ public X11PlatformIdle(IWindowInfo info)
+ {
+ display = (info as OpenTK.Platform.X11.WindowInfo).Display;
+ }
+
+ #region IPlatformIdle Members
- ///
- /// Gets the idle status of the control.
- ///
public bool IsIdle
{
get
{
- if (glControl == null)
- this.CreateContext();
-
- return glControl.IsIdle;
+ lock (get_lock)
+ {
+ return OpenTK.Platform.X11.Functions.XPending(display) == 0;
+ }
}
}
#endregion
-
- #region public IGLContext Context
-
- ///
- /// Gets the opengl context associated with this control.
- ///
- public IGLContext Context
- {
- get
- {
- if (glControl == null)
- this.CreateContext();
-
- return glControl.Context;
- }
- }
-
- #endregion
-
- #region DisplayMode changes
-
- ///
- /// Selects the fullscreen DisplayMode closest to the DisplayMode requested.
- ///
- ///
- /// The fullscreen DisplayMode to match, or null to get the current screen DisplayMode.
- ///
- /// The DisplayMode closest to the requested one, or null if no DisplayModes are available.
- ///
- /// SetDisplayMode
- ///
- public DisplayMode SelectDisplayMode(DisplayMode mode)
- {
- throw new NotImplementedException();
- //return glWindow.SelectDisplayMode(mode);
- }
-
- ///
- /// Selects the fullscreen DisplayMode closest to the DisplayMode requested, accoriding to the specified
- /// parameters.
- ///
- ///
- /// The fullscreen DisplayMode to match, or null to get the current screen DisplayMode.
- ///
- ///
- /// The DisplayModeMatchOptions flags that indicate how to search for the requested DisplayMode.
- ///
- ///
- /// The DisplayMode closest to the requested one, or null if no DisplayModes are available or
- /// DisplayModeMatchOptions.ExactMatch was passed.
- ///
- ///
- /// SetDisplayMode
- ///
- public DisplayMode SelectDisplayMode(DisplayMode mode, DisplayModeMatchOptions options)
- {
- throw new NotImplementedException();
- //return glWindow.SelectDisplayMode(mode, options);
- }
-
- ///
- /// Sets the requested DisplayMode.
- ///
- ///
- /// The fulscreen DisplayMode to set. Passing null will return the application to windowed
- /// mode.
- ///
- ///
- /// Use SelectDisplayMode to select one of the available fullscreen modes.
- ///
- /// If the mode requested is not available, this function will throw a
- /// DisplayModeNotAvailable exception.
- ///
- ///
- /// Pass null to return to windowed mode. The previous desktop DisplayMode will be automatically reset by this
- /// function. This function cannot be used to permanently change the user's desktop DisplayMode.
- ///
- /// SelectDisplayMode
- /// DisplayModeNotAvailable exception
- ///
- public void SetDisplayMode(DisplayMode mode)
- {
- throw new NotImplementedException();
- //glWindow.SetDisplayMode(mode);
- }
-
- #endregion
-
- #endregion
-
}
+
+ internal class PlatformIdle : IPlatformIdle
+ {
+ IPlatformIdle implementation;
+
+ public PlatformIdle(IWindowInfo info)
+ {
+ switch (System.Environment.OSVersion.Platform)
+ {
+ case PlatformID.Unix:
+ case (PlatformID)128:
+ implementation = new X11PlatformIdle(info);
+ break;
+
+ case PlatformID.Win32NT:
+ case PlatformID.Win32S:
+ case PlatformID.Win32Windows:
+ case PlatformID.WinCE:
+ implementation = new WinPlatformIdle(info);
+ break;
+
+ default:
+ throw new PlatformNotSupportedException();
+ }
+ }
+
+ #region IPlatformIdle Members
+
+ public bool IsIdle
+ {
+ get { return implementation.IsIdle; }
+ }
+
+ #endregion
+ }
+
+ internal class DummyPlatformIdle : IPlatformIdle
+ {
+ #region IPlatformIdle Members
+
+ public bool IsIdle
+ {
+ get { return false; }
+ }
+
+ #endregion
+ }
+
+ #endregion
}
diff --git a/Source/OpenTK/Platform/DummyGLControl.cs b/Source/OpenTK/Platform/DummyGLControl.cs
deleted file mode 100644
index c0476de6..00000000
--- a/Source/OpenTK/Platform/DummyGLControl.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-#region --- License ---
-/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos
- * See license.txt for license info
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace OpenTK.Platform
-{
- ///
- /// An IGLControl implementation to be used inside the Visual Studio designer.
- ///
- internal sealed class DummyGLControl : IGLControl
- {
- bool fullscreen;
- IGLContext glContext = new DummyGLContext();
-
- #region --- IGLControl Members ---
-
- public bool IsIdle
- {
- get
- {
- return false;
- }
- }
-
- public bool Fullscreen
- {
- get
- {
- return fullscreen;
- }
- set
- {
- fullscreen = value;
- }
- }
-
- public IGLContext Context
- {
- get
- {
- return glContext;
- }
- }
-
- #endregion
- }
-}
diff --git a/Source/OpenTK/Platform/IGLControl.cs b/Source/OpenTK/Platform/IGLControl.cs
deleted file mode 100644
index d5461e7c..00000000
--- a/Source/OpenTK/Platform/IGLControl.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-#region --- License ---
-/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos
- * See license.txt for license info
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-using OpenTK.OpenGL;
-
-namespace OpenTK.Platform
-{
- public interface IGLControl
- {
- bool IsIdle { get; }
- bool Fullscreen { get; set; }
- IGLContext Context { get; }
- }
-}
diff --git a/Source/OpenTK/Platform/Windows/WinGLControl.cs b/Source/OpenTK/Platform/Windows/WinGLControl.cs
deleted file mode 100644
index 8d8620d6..00000000
--- a/Source/OpenTK/Platform/Windows/WinGLControl.cs
+++ /dev/null
@@ -1,144 +0,0 @@
-#region --- License ---
-/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos
- * Contributions from Erik Ylvisaker
- * See license.txt for license info
- */
-#endregion
-
-#region --- Using directives ---
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Windows.Forms;
-using System.Diagnostics;
-
-#endregion
-
-namespace OpenTK.Platform.Windows
-{
- sealed class WinGLControl : IGLControl, IDisposable
- {
- private WinGLContext glContext;
- private bool fullscreen;
- private ResizeEventArgs resizeEventArgs = new ResizeEventArgs();
- private DisplayMode mode;
-
- private bool disposed;
- private MSG msg; // Used only by the IsIdle event.
-
- #region --- Constructors ---
-
- public WinGLControl(UserControl c, DisplayMode mode)
- {
- this.mode = mode;
-
- c.HandleCreated += new EventHandler(c_HandleCreated);
- c.HandleDestroyed += new EventHandler(c_HandleDestroyed);
- }
-
- #endregion
-
- void c_HandleCreated(object sender, EventArgs e)
- {
- Debug.Print("GLControl handle created, creating WinGLContext.");
- Debug.Indent();
-
- try
- {
- if (glContext != null)
- glContext.Dispose();
-
- glContext = new WinGLContext(mode, new WindowInfo(sender as Control));
- glContext.CreateContext();
- glContext.MakeCurrent();
- }
- catch (ApplicationException expt)
- {
- Debug.Print(expt.ToString());
- throw;
- }
- finally
- {
- Debug.Unindent();
- }
- }
-
- void c_HandleDestroyed(object sender, EventArgs e)
- {
- glContext.Dispose();
- }
-
- #region --- IGLControl members ---
-
- #region public bool IsIdle
-
- public bool IsIdle
- {
- get
- {
- return !Functions.PeekMessage(ref msg, IntPtr.Zero, 0, 0, 0);
- }
- }
-
- #endregion
-
- #region public bool Fullscreen
-
- public bool Fullscreen
- {
- get
- {
- return fullscreen;
- }
- set
- {
- fullscreen = false;
- //throw new NotImplementedException();
- }
- }
-
- #endregion
-
- #region public IGLContext Context
-
- public IGLContext Context
- {
- get { return glContext; }
- }
-
- #endregion
-
- #endregion
-
- #region --- IDisposable Members ---
-
- public void Dispose()
- {
- this.Dispose(true);
- //GC.SuppressFinalize(this);
- }
-
- private void Dispose(bool calledManually)
- {
- if (!disposed)
- {
- // Clean unmanaged resources here:
-
- if (calledManually)
- {
- // Safe to clean managed resources
- glContext.Dispose();
- }
- disposed = true;
- }
- }
- /*
- ~WinGLControl()
- {
- Dispose(false);
- }
- */
- #endregion
- }
-}
diff --git a/Source/OpenTK/Platform/X11/X11GLControl.cs b/Source/OpenTK/Platform/X11/X11GLControl.cs
deleted file mode 100644
index a51855d6..00000000
--- a/Source/OpenTK/Platform/X11/X11GLControl.cs
+++ /dev/null
@@ -1,223 +0,0 @@
-#region --- License ---
-/* Copyright (c) 2007 Stefanos Apostolopoulos
- * See license.txt for license info
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Windows.Forms;
-using System.Drawing;
-using System.Diagnostics;
-
-namespace OpenTK.Platform.X11
-{
- sealed class X11GLControl : IGLControl
- {
- WindowInfo info = new WindowInfo();
- //DisplayMode mode;
- private Type xplatui;
- IGLContext glContext;
-
- private bool disposed;
- private bool fullscreen;
-
- #region --- Contructors ---
-
- #region public X11GLControl(UserControl c)
-
- public X11GLControl(UserControl c)
- {
- Debug.WriteLine("Creating opengl control (X11GLControl driver)");
- Debug.Indent();
-
- Utilities.ThrowOnX11Error = true;
-
- if (c == null/* || c.TopLevelControl == null*/)
- {
- throw new ArgumentException("UserControl c may not be null.");
- }
-
- c.HandleCreated += new EventHandler(c_HandleCreated);
- c.HandleDestroyed += new EventHandler(c_HandleDestroyed);
-
- xplatui = Type.GetType("System.Windows.Forms.XplatUIX11, System.Windows.Forms");
- if (xplatui == null)
- throw new ApplicationException("Could not get System.Windows.Forms.XplatUIX11 through reflection. Unsupported platform or Mono runtime version, aborting.");
-
- info.Display = (IntPtr)xplatui.GetField("DisplayHandle",
- System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
- info.RootWindow = (IntPtr)xplatui.GetField("RootWindow",
- System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
- info.Screen = (int)xplatui.GetField("ScreenNo",
- System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic).GetValue(null);
- Debug.Print("Data read from System.Windows.Forms.XplatUIX11: {0}", info.ToString());
-
- //this.mode = mode;
- glContext = new GLContext(null, info);
- //glContext.PrepareContext(info);
-
- info.VisualInfo = (glContext.Info as X11.WindowInfo).VisualInfo;
-
- Debug.Print("Setting XplatUIX11.CustomVisual");
- xplatui.GetField("CustomVisual", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)
- .SetValue(null, info.VisualInfo.visual);
-
- Debug.Print("Setting XplatUIX11.CustomColormap");
- xplatui.GetField("CustomColormap", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic)
- .SetValue(null, API.CreateColormap(info.Display, info.RootWindow, info.VisualInfo.visual, 0));
-
- Debug.Unindent();
- }
-
- #endregion
-
- #region void c_HandleCreated(object sender, EventArgs e)
-
- void c_HandleCreated(object sender, EventArgs e)
- {
- UserControl c = (sender as UserControl);
- Debug.Print("GLControl handle created, creating X11GLContext.");
- Debug.Indent();
-
- try
- {
- (glContext.Info as X11.WindowInfo).Handle = info.Handle = (sender as UserControl).Handle;
- glContext.CreateContext(true, null);
- glContext.MakeCurrent();
- }
- catch (ApplicationException expt)
- {
- Debug.Print(expt.ToString());
- throw;
- }
- finally
- {
- Debug.Unindent();
- }
- }
-
- #endregion
-
- #region void c_HandleDestroyed(object sender, EventArgs e)
-
- void c_HandleDestroyed(object sender, EventArgs e)
- {
- Debug.Print("X11GLControl handle destroyed, disposing X11GLContext.");
- glContext.Dispose();
- }
-
- #endregion
-
- #region private IntPtr FindColormap()
-
- ///
- /// Finds a colormap suitable for use with the GLControl.
- ///
- /// A pointer to the colormap
- ///
- /// If the visual of the GLControl matches the default visual, the function returns
- /// the default colormap (i.e. the colormap of the root window). Otherwise, it creates
- /// a new, private colormap.
- ///
- private IntPtr FindColormap()
- {
- if (info.VisualInfo.visual == Functions.XDefaultVisual(info.Display, info.Screen))
- {
- return Functions.XDefaultColormap(info.Display, info.Screen);
- }
-
- return API.CreateColormap(info.Display, info.RootWindow,
- (glContext.Info as X11.WindowInfo).VisualInfo.visual, 0/*AllocNone*/);
- }
-
- #endregion
-
- #endregion
-
- #region --- IGLControl Members ---
-
- public event CreateEvent Create;
-
- private void OnCreate(object sender, EventArgs e)
- {
- if (this.Create != null)
- this.Create(sender, e);
- }
-
- #region public bool IsIdle
-
- public bool IsIdle
- {
- get
- {
- return API.Pending(info.Display) == 0;
- }
- }
-
- #endregion
-
- #region public bool Fullscreen
-
- public bool Fullscreen
- {
- get
- {
- return fullscreen;
- }
- set
- {
- //throw new Exception("The method or operation is not implemented.");
- fullscreen = false;
- }
- }
-
- #endregion
-
- #region public IGLContext Context
-
- public IGLContext Context
- {
- get
- {
- return glContext;
- }
- }
-
- #endregion
-
- #endregion
-
- #region --- IDisposable Members ---
-
- public void Dispose()
- {
- this.Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- private void Dispose(bool manuallyCalled)
- {
- if (!disposed)
- {
- // Clean unmanaged resources:
- // Nothing
-
- if (manuallyCalled)
- {
- // Clean managed resources, too
- glContext.Dispose();
- }
- }
- disposed = true;
- }
-
- ~X11GLControl()
- {
- this.Dispose(false);
- }
-
- #endregion
- }
-}