2007-07-23 00:15:18 +00:00
|
|
|
|
#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;
|
2007-10-05 06:52:40 +00:00
|
|
|
|
using System.Data;
|
2007-07-23 00:15:18 +00:00
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Windows.Forms;
|
|
|
|
|
|
|
|
|
|
using OpenTK.Platform;
|
2008-01-31 14:22:37 +00:00
|
|
|
|
using OpenTK.Graphics;
|
2007-07-23 00:15:18 +00:00
|
|
|
|
|
|
|
|
|
namespace OpenTK
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
2007-10-05 06:52:40 +00:00
|
|
|
|
/// Defines a UserControl with OpenGL rendering capabilities.
|
2007-07-23 00:15:18 +00:00
|
|
|
|
/// </summary>
|
2007-10-05 06:52:40 +00:00
|
|
|
|
public partial class GLControl : UserControl
|
2007-07-23 00:15:18 +00:00
|
|
|
|
{
|
2008-01-31 13:17:42 +00:00
|
|
|
|
IGraphicsContext context;
|
2008-02-28 15:26:13 +00:00
|
|
|
|
GraphicsMode format;
|
2008-02-28 13:57:07 +00:00
|
|
|
|
IGLControlHelper helper;
|
2007-07-23 00:15:18 +00:00
|
|
|
|
|
2007-10-05 06:52:40 +00:00
|
|
|
|
#region --- Constructor ---
|
2007-07-23 00:15:18 +00:00
|
|
|
|
|
2007-11-11 19:28:43 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Constructs a new GLControl.
|
|
|
|
|
/// </summary>
|
2007-07-23 00:15:18 +00:00
|
|
|
|
public GLControl()
|
2008-02-28 15:26:13 +00:00
|
|
|
|
: this(GraphicsMode.Default)
|
2008-02-28 13:57:07 +00:00
|
|
|
|
{ }
|
2007-10-15 11:15:34 +00:00
|
|
|
|
|
2007-11-11 19:28:43 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Constructs a new GLControl with the specified DisplayMode.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="mode"></param>
|
2007-10-15 11:15:34 +00:00
|
|
|
|
public GLControl(DisplayMode mode)
|
2008-02-28 13:57:07 +00:00
|
|
|
|
: this(mode.ToGraphicsFormat())
|
|
|
|
|
{ }
|
|
|
|
|
|
2008-02-28 15:26:13 +00:00
|
|
|
|
public GLControl(GraphicsMode format)
|
2007-07-23 00:15:18 +00:00
|
|
|
|
{
|
|
|
|
|
InitializeComponent();
|
2007-08-20 10:46:37 +00:00
|
|
|
|
|
2007-11-12 08:33:24 +00:00
|
|
|
|
this.SetStyle(ControlStyles.Opaque, true);
|
2007-08-20 10:46:37 +00:00
|
|
|
|
this.SetStyle(ControlStyles.UserPaint, true);
|
|
|
|
|
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
|
2008-01-06 02:30:12 +00:00
|
|
|
|
DoubleBuffered = false;
|
2007-10-15 11:15:34 +00:00
|
|
|
|
|
2008-02-28 13:57:07 +00:00
|
|
|
|
this.format = format;
|
2007-10-24 16:41:40 +00:00
|
|
|
|
|
|
|
|
|
this.CreateControl();
|
2007-09-02 00:19:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-08-20 10:46:37 +00:00
|
|
|
|
#endregion
|
2007-09-02 08:07:09 +00:00
|
|
|
|
|
2008-02-28 13:57:07 +00:00
|
|
|
|
#region --- Protected Methods ---
|
2007-08-20 10:46:37 +00:00
|
|
|
|
|
2007-10-05 06:52:40 +00:00
|
|
|
|
protected override void OnHandleCreated(EventArgs e)
|
2007-08-20 10:46:37 +00:00
|
|
|
|
{
|
2007-10-05 06:52:40 +00:00
|
|
|
|
base.OnHandleCreated(e);
|
2008-02-28 13:57:07 +00:00
|
|
|
|
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();
|
2007-10-15 11:15:34 +00:00
|
|
|
|
this.CreateContext();
|
2007-10-05 06:52:40 +00:00
|
|
|
|
}
|
2007-07-23 00:15:18 +00:00
|
|
|
|
|
2007-10-05 06:52:40 +00:00
|
|
|
|
protected override void OnHandleDestroyed(EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
base.OnHandleDestroyed(e);
|
2007-10-15 11:15:34 +00:00
|
|
|
|
this.DestroyContext();
|
2007-07-23 00:15:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-09-02 08:07:09 +00:00
|
|
|
|
#endregion
|
|
|
|
|
|
2008-02-28 13:57:07 +00:00
|
|
|
|
#region --- Public Methods ---
|
2007-10-05 06:52:40 +00:00
|
|
|
|
|
2008-02-28 13:57:07 +00:00
|
|
|
|
#region public void SwapBuffers()
|
2007-09-02 08:07:09 +00:00
|
|
|
|
|
2007-07-23 00:15:18 +00:00
|
|
|
|
/// <summary>
|
2008-02-28 13:57:07 +00:00
|
|
|
|
/// Swaps the front and back buffers, presenting the rendered scene to the screen.
|
2007-07-23 00:15:18 +00:00
|
|
|
|
/// </summary>
|
2008-02-28 13:57:07 +00:00
|
|
|
|
public void SwapBuffers()
|
2007-07-23 00:15:18 +00:00
|
|
|
|
{
|
2008-02-28 13:57:07 +00:00
|
|
|
|
Context.SwapBuffers();
|
2007-07-23 00:15:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-09-02 08:07:09 +00:00
|
|
|
|
#endregion
|
|
|
|
|
|
2008-02-28 13:57:07 +00:00
|
|
|
|
#region public void MakeCurrent()
|
2007-09-02 08:07:09 +00:00
|
|
|
|
|
2007-07-23 00:15:18 +00:00
|
|
|
|
/// <summary>
|
2008-02-28 13:57:07 +00:00
|
|
|
|
/// Makes the underlying this GLControl current in the calling thread.
|
|
|
|
|
/// All OpenGL commands issued are hereafter interpreted by this GLControl.
|
2007-07-23 00:15:18 +00:00
|
|
|
|
/// </summary>
|
2008-02-28 13:57:07 +00:00
|
|
|
|
public void MakeCurrent()
|
2007-07-23 00:15:18 +00:00
|
|
|
|
{
|
2008-02-28 13:57:07 +00:00
|
|
|
|
Context.MakeCurrent();
|
2007-07-23 00:15:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2008-02-28 13:57:07 +00:00
|
|
|
|
#region public void CreateContext()
|
|
|
|
|
|
2007-07-23 00:15:18 +00:00
|
|
|
|
/// <summary>
|
2008-02-28 13:57:07 +00:00
|
|
|
|
/// Creates a GraphicsContext and attaches it to this GLControl.
|
2007-07-23 00:15:18 +00:00
|
|
|
|
/// </summary>
|
2008-02-28 13:57:07 +00:00
|
|
|
|
public void CreateContext()
|
2007-07-23 00:15:18 +00:00
|
|
|
|
{
|
2008-02-28 13:57:07 +00:00
|
|
|
|
if (context != null)
|
|
|
|
|
throw new InvalidOperationException("GLControl already contains an OpenGL context.");
|
|
|
|
|
if (format == null)
|
2008-02-28 15:26:13 +00:00
|
|
|
|
format = GraphicsMode.Default;
|
2008-02-28 13:57:07 +00:00
|
|
|
|
|
|
|
|
|
if (!this.DesignMode)
|
2007-07-23 00:15:18 +00:00
|
|
|
|
{
|
2008-02-28 13:57:07 +00:00
|
|
|
|
// 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);
|
2007-07-23 00:15:18 +00:00
|
|
|
|
}
|
2008-02-28 13:57:07 +00:00
|
|
|
|
else
|
|
|
|
|
context = new DummyGLContext(format);
|
2007-07-23 00:15:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-10-05 06:52:40 +00:00
|
|
|
|
#endregion
|
|
|
|
|
|
2008-02-28 13:57:07 +00:00
|
|
|
|
#region public void DestroyContext()
|
2007-10-05 06:52:40 +00:00
|
|
|
|
|
2007-07-23 00:15:18 +00:00
|
|
|
|
/// <summary>
|
2008-02-28 13:57:07 +00:00
|
|
|
|
/// Destroys the GraphicsContext attached to this GLControl.
|
2007-07-23 00:15:18 +00:00
|
|
|
|
/// </summary>
|
2008-02-28 13:57:07 +00:00
|
|
|
|
/// <exception cref="NullReferenceException">Occurs when no GraphicsContext is attached.</exception>
|
|
|
|
|
public void DestroyContext()
|
2007-07-23 00:15:18 +00:00
|
|
|
|
{
|
2008-02-28 13:57:07 +00:00
|
|
|
|
Context.Dispose();
|
|
|
|
|
Context = null;
|
2007-07-23 00:15:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2008-02-28 13:57:07 +00:00
|
|
|
|
#region public bool IsIdle
|
2008-01-11 20:36:43 +00:00
|
|
|
|
|
2007-10-15 11:15:34 +00:00
|
|
|
|
/// <summary>
|
2008-02-28 13:57:07 +00:00
|
|
|
|
/// Gets a value indicating whether the current thread contains pending system messages.
|
2007-10-15 11:15:34 +00:00
|
|
|
|
/// </summary>
|
2008-02-28 13:57:07 +00:00
|
|
|
|
[Browsable(false)]
|
|
|
|
|
public bool IsIdle
|
2007-10-15 11:15:34 +00:00
|
|
|
|
{
|
2008-02-28 13:57:07 +00:00
|
|
|
|
get { return helper.IsIdle; }
|
2007-10-15 11:15:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2008-02-28 13:57:07 +00:00
|
|
|
|
#region public IGraphicsContext Context
|
2007-07-23 00:15:18 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
2008-02-28 13:57:07 +00:00
|
|
|
|
/// Gets an interface to the underlying GraphicsContext used by this GLControl.
|
2007-07-23 00:15:18 +00:00
|
|
|
|
/// </summary>
|
2008-02-28 13:57:07 +00:00
|
|
|
|
[Browsable(false)]
|
|
|
|
|
public IGraphicsContext Context
|
2007-07-23 00:15:18 +00:00
|
|
|
|
{
|
2008-02-28 13:57:07 +00:00
|
|
|
|
get { return context; }
|
|
|
|
|
private set { context = value; }
|
2007-07-23 00:15:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2008-02-28 13:57:07 +00:00
|
|
|
|
#region public float AspectRatio
|
2007-07-23 00:15:18 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
2008-02-28 13:57:07 +00:00
|
|
|
|
/// Gets the aspect ratio of this GLControl.
|
2007-07-23 00:15:18 +00:00
|
|
|
|
/// </summary>
|
2008-02-28 13:57:07 +00:00
|
|
|
|
[Description("The aspect ratio of the client area of this GLControl.")]
|
|
|
|
|
public float AspectRatio
|
2007-07-23 00:15:18 +00:00
|
|
|
|
{
|
2008-02-28 13:57:07 +00:00
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return this.ClientSize.Width / (float)this.ClientSize.Height;
|
|
|
|
|
}
|
2007-10-05 06:52:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2008-02-28 13:57:07 +00:00
|
|
|
|
#region public bool VSync
|
|
|
|
|
|
2007-10-15 11:15:34 +00:00
|
|
|
|
/// <summary>
|
2008-02-28 13:57:07 +00:00
|
|
|
|
/// Gets or sets a value indicating whether vsync is active for this GLControl.
|
2007-10-15 11:15:34 +00:00
|
|
|
|
/// </summary>
|
2008-02-28 13:57:07 +00:00
|
|
|
|
[Description("Indicates whether GLControl updates are synced to the monitor's refresh.")]
|
|
|
|
|
public bool VSync
|
2007-10-15 11:15:34 +00:00
|
|
|
|
{
|
2008-02-28 13:57:07 +00:00
|
|
|
|
get
|
2007-10-15 11:15:34 +00:00
|
|
|
|
{
|
2008-02-28 13:57:07 +00:00
|
|
|
|
if (Context != null)
|
|
|
|
|
return Context.VSync;
|
|
|
|
|
return false;
|
2007-10-15 11:15:34 +00:00
|
|
|
|
}
|
2008-02-28 13:57:07 +00:00
|
|
|
|
set
|
2007-10-15 11:15:34 +00:00
|
|
|
|
{
|
2008-02-28 13:57:07 +00:00
|
|
|
|
if (Context != null)
|
|
|
|
|
Context.VSync = value;
|
2007-10-15 11:15:34 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2008-02-28 13:57:07 +00:00
|
|
|
|
#region public GraphicsFormat GraphicsFormat
|
2007-10-15 11:15:34 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
2008-02-28 13:57:07 +00:00
|
|
|
|
/// Gets the GraphicsFormat of the GraphicsContext attached to this GLControl.
|
2007-10-15 11:15:34 +00:00
|
|
|
|
/// </summary>
|
2008-02-28 13:57:07 +00:00
|
|
|
|
/// <remarks>
|
|
|
|
|
/// To change the GraphicsFormat, you must destroy and recreate the GLControl.
|
|
|
|
|
/// </remarks>
|
2008-02-28 15:26:13 +00:00
|
|
|
|
public GraphicsMode GraphicsFormat
|
2007-10-15 11:15:34 +00:00
|
|
|
|
{
|
2008-02-28 13:57:07 +00:00
|
|
|
|
get { return (Context as IGLContextInternal).GraphicsFormat; }
|
2007-10-15 11:15:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2007-10-05 06:52:40 +00:00
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region internal interface IPlatformIdle
|
2008-02-28 13:57:07 +00:00
|
|
|
|
#if false
|
2007-10-05 06:52:40 +00:00
|
|
|
|
internal interface IPlatformIdle
|
|
|
|
|
{
|
|
|
|
|
bool IsIdle { get; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal class X11PlatformIdle : IPlatformIdle
|
|
|
|
|
{
|
|
|
|
|
object get_lock = new object();
|
|
|
|
|
IntPtr display;
|
2007-07-23 00:15:18 +00:00
|
|
|
|
|
2007-11-11 19:28:43 +00:00
|
|
|
|
public X11PlatformIdle(WindowInfo info)
|
2007-07-23 00:15:18 +00:00
|
|
|
|
{
|
2008-01-24 21:18:23 +00:00
|
|
|
|
display = new OpenTK.Platform.X11.WindowInfo(info).Display;//((OpenTK.Platform.X11.WindowInfo)info).Display;
|
2007-07-23 00:15:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-10-05 06:52:40 +00:00
|
|
|
|
#region IPlatformIdle Members
|
|
|
|
|
|
|
|
|
|
public bool IsIdle
|
2007-07-23 00:15:18 +00:00
|
|
|
|
{
|
2007-10-05 06:52:40 +00:00
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
lock (get_lock)
|
|
|
|
|
{
|
|
|
|
|
return OpenTK.Platform.X11.Functions.XPending(display) == 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
2007-07-23 00:15:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
2007-10-05 06:52:40 +00:00
|
|
|
|
#endregion
|
|
|
|
|
}
|
2008-02-28 13:57:07 +00:00
|
|
|
|
#endif
|
2007-10-05 06:52:40 +00:00
|
|
|
|
|
2008-02-28 13:57:07 +00:00
|
|
|
|
#endregion
|
2007-07-23 00:15:18 +00:00
|
|
|
|
|
2008-02-28 13:57:07 +00:00
|
|
|
|
#region internal interface IGLControlHelper
|
2007-10-05 06:52:40 +00:00
|
|
|
|
|
2008-02-28 13:57:07 +00:00
|
|
|
|
internal interface IGLControlHelper
|
2007-10-05 06:52:40 +00:00
|
|
|
|
{
|
2008-02-28 13:57:07 +00:00
|
|
|
|
IWindowInfo WindowInfo { get; }
|
|
|
|
|
bool IsIdle { get; }
|
2007-07-23 00:15:18 +00:00
|
|
|
|
}
|
2007-10-05 06:52:40 +00:00
|
|
|
|
|
|
|
|
|
#endregion
|
2007-07-23 00:15:18 +00:00
|
|
|
|
}
|