#region --- License --- /* Copyright (c) 2006, 2007 Stefanos Apostolopoulos * See license.txt for license info */ #endregion using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Text; using System.Windows.Forms; using OpenTK.Platform; using OpenTK.Graphics; namespace OpenTK { /// /// Defines a UserControl with OpenGL rendering capabilities. /// public partial class GLControl : UserControl { IGraphicsContext context; GraphicsMode format; IGLControlHelper helper; #region --- Constructor --- /// /// Constructs a new GLControl. /// public GLControl() : this(GraphicsMode.Default) { } /// /// Constructs a new GLControl with the specified DisplayMode. /// /// public GLControl(DisplayMode mode) : this(mode.ToGraphicsFormat()) { } public GLControl(GraphicsMode format) { InitializeComponent(); this.SetStyle(ControlStyles.Opaque, true); this.SetStyle(ControlStyles.UserPaint, true); this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); DoubleBuffered = false; this.format = format; this.CreateControl(); } #endregion #region --- Protected Methods --- protected override void OnHandleCreated(EventArgs e) { base.OnHandleCreated(e); if (Configuration.RunningOnWindows) helper = new Platform.Windows.WinGLControlHelper(this); else if (Configuration.RunningOnX11) throw new NotImplementedException(); //helper = new Platform.X11.X11GLControlHelper(this); else if (Configuration.RunningOnOSX) throw new NotImplementedException(); this.CreateContext(); } protected override void OnHandleDestroyed(EventArgs e) { base.OnHandleDestroyed(e); this.DestroyContext(); } #endregion #region --- Public Methods --- #region public void SwapBuffers() /// /// Swaps the front and back buffers, presenting the rendered scene to the screen. /// public void SwapBuffers() { Context.SwapBuffers(); } #endregion #region public void MakeCurrent() /// /// Makes the underlying this GLControl current in the calling thread. /// All OpenGL commands issued are hereafter interpreted by this GLControl. /// public void MakeCurrent() { Context.MakeCurrent(); } #endregion #region public void CreateContext() /// /// Creates a GraphicsContext and attaches it to this GLControl. /// public void CreateContext() { if (context != null) throw new InvalidOperationException("GLControl already contains an OpenGL context."); if (format == null) format = GraphicsMode.Default; if (!this.DesignMode) { // Note: Mono's implementation of Windows.Forms on X11 does not allow the context to // have a different colordepth from the parent window. context = new GraphicsContext(format, helper.WindowInfo); } else context = new DummyGLContext(format); } #endregion #region public void DestroyContext() /// /// Destroys the GraphicsContext attached to this GLControl. /// /// Occurs when no GraphicsContext is attached. public void DestroyContext() { Context.Dispose(); Context = null; } #endregion #region public bool IsIdle /// /// Gets a value indicating whether the current thread contains pending system messages. /// [Browsable(false)] public bool IsIdle { get { return helper.IsIdle; } } #endregion #region public IGraphicsContext Context /// /// Gets an interface to the underlying GraphicsContext used by this GLControl. /// [Browsable(false)] public IGraphicsContext Context { get { return context; } private set { context = value; } } #endregion #region public float AspectRatio /// /// Gets the aspect ratio of this GLControl. /// [Description("The aspect ratio of the client area 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. /// [Description("Indicates whether GLControl updates are synced to the monitor's refresh.")] public bool VSync { get { if (Context != null) return Context.VSync; return false; } set { if (Context != null) Context.VSync = value; } } #endregion #region public GraphicsFormat GraphicsFormat /// /// Gets the GraphicsFormat of the GraphicsContext attached to this GLControl. /// /// /// To change the GraphicsFormat, you must destroy and recreate the GLControl. /// public GraphicsMode GraphicsFormat { get { return (Context as IGLContextInternal).GraphicsFormat; } } #endregion #endregion } #region internal interface IPlatformIdle #if false internal interface IPlatformIdle { bool IsIdle { get; } } internal class X11PlatformIdle : IPlatformIdle { object get_lock = new object(); IntPtr display; public X11PlatformIdle(WindowInfo info) { display = new OpenTK.Platform.X11.WindowInfo(info).Display;//((OpenTK.Platform.X11.WindowInfo)info).Display; } #region IPlatformIdle Members public bool IsIdle { get { lock (get_lock) { return OpenTK.Platform.X11.Functions.XPending(display) == 0; } } } #endregion } #endif #endregion #region internal interface IGLControlHelper internal interface IGLControlHelper { IWindowInfo WindowInfo { get; } bool IsIdle { get; } } #endregion }