00001 #region License
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #endregion
00027
00028 using System;
00029 using System.Collections.Generic;
00030 using System.ComponentModel;
00031 using System.Diagnostics;
00032 using System.Drawing;
00033 using System.Data;
00034 using System.Text;
00035 using System.Windows.Forms;
00036
00037 using OpenTK.Platform;
00038 using OpenTK.Graphics;
00039 using OpenTK.Graphics.OpenGL;
00040
00041 namespace OpenTK
00042 {
00046 public partial class GLControl : UserControl
00047 {
00048 IGraphicsContext context;
00049 IGLControl implementation;
00050 GraphicsMode format;
00051 int major, minor;
00052 GraphicsContextFlags flags;
00053 bool? initial_vsync_value;
00054
00055
00056
00057
00058 bool resize_event_suppressed;
00059
00060 #region --- Constructors ---
00061
00065 public GLControl()
00066 : this(GraphicsMode.Default)
00067 { }
00068
00073 public GLControl(GraphicsMode mode)
00074 : this(mode, 1, 0, GraphicsContextFlags.Default)
00075 { }
00076
00084 public GLControl(GraphicsMode mode, int major, int minor, GraphicsContextFlags flags)
00085 {
00086 if (mode == null)
00087 throw new ArgumentNullException("mode");
00088
00089 SetStyle(ControlStyles.Opaque, true);
00090 SetStyle(ControlStyles.UserPaint, true);
00091 SetStyle(ControlStyles.AllPaintingInWmPaint, true);
00092 DoubleBuffered = false;
00093
00094 this.format = mode;
00095 this.major = major;
00096 this.minor = minor;
00097 this.flags = flags;
00098
00099 InitializeComponent();
00100 }
00101
00102 #endregion
00103
00104 #region --- Private Methods ---
00105
00106 IGLControl Implementation
00107 {
00108 get
00109 {
00110 ValidateState();
00111
00112 return implementation;
00113 }
00114 }
00115
00116 void ValidateState()
00117 {
00118 if (IsDisposed)
00119 throw new ObjectDisposedException(GetType().Name);
00120
00121 if (!IsHandleCreated)
00122 CreateControl();
00123
00124 if (implementation == null || context == null || context.IsDisposed)
00125 RecreateHandle();
00126 }
00127
00128 #endregion
00129
00130 #region --- Protected Methods ---
00131
00134 protected override void OnHandleCreated(EventArgs e)
00135 {
00136 if (context != null)
00137 context.Dispose();
00138
00139 if (implementation != null)
00140 implementation.WindowInfo.Dispose();
00141
00142 if (DesignMode)
00143 implementation = new DummyGLControl();
00144 else
00145 implementation = new GLControlFactory().CreateGLControl(format, this);
00146
00147 context = implementation.CreateContext(major, minor, flags);
00148 MakeCurrent();
00149
00150 if (!DesignMode)
00151 ((IGraphicsContextInternal)Context).LoadAll();
00152
00153
00154 if (initial_vsync_value.HasValue)
00155 {
00156 Context.VSync = initial_vsync_value.Value;
00157 initial_vsync_value = null;
00158 }
00159
00160 base.OnHandleCreated(e);
00161
00162 if (resize_event_suppressed)
00163 {
00164 OnResize(EventArgs.Empty);
00165 resize_event_suppressed = false;
00166 }
00167 }
00168
00171 protected override void OnHandleDestroyed(EventArgs e)
00172 {
00173 if (context != null)
00174 {
00175 context.Dispose();
00176 context = null;
00177 }
00178
00179 if (implementation != null)
00180 {
00181 implementation.WindowInfo.Dispose();
00182 implementation = null;
00183 }
00184
00185 base.OnHandleDestroyed(e);
00186 }
00187
00192 protected override void OnPaint(PaintEventArgs e)
00193 {
00194 ValidateState();
00195
00196 if (DesignMode)
00197 e.Graphics.Clear(BackColor);
00198
00199 base.OnPaint(e);
00200 }
00201
00208 protected override void OnResize(EventArgs e)
00209 {
00210
00211 if (!IsHandleCreated)
00212 {
00213 resize_event_suppressed = true;
00214 return;
00215 }
00216
00217 if (context != null)
00218 context.Update(Implementation.WindowInfo);
00219
00220 base.OnResize(e);
00221 }
00222
00227 protected override void OnParentChanged(EventArgs e)
00228 {
00229 if (context != null)
00230 context.Update(Implementation.WindowInfo);
00231
00232 base.OnParentChanged(e);
00233 }
00234
00235 #endregion
00236
00237 #region --- Public Methods ---
00238
00239 #region public void SwapBuffers()
00240
00244 public void SwapBuffers()
00245 {
00246 ValidateState();
00247 Context.SwapBuffers();
00248 }
00249
00250 #endregion
00251
00252 #region public void MakeCurrent()
00253
00258 public void MakeCurrent()
00259 {
00260 ValidateState();
00261 Context.MakeCurrent(Implementation.WindowInfo);
00262 }
00263
00264 #endregion
00265
00266 #region public bool IsIdle
00267
00271 [Browsable(false)]
00272 public bool IsIdle
00273 {
00274 get
00275 {
00276 ValidateState();
00277 return Implementation.IsIdle;
00278 }
00279 }
00280
00281 #endregion
00282
00283 #region public IGraphicsContext Context
00284
00288 [Browsable(false)]
00289 public IGraphicsContext Context
00290 {
00291 get
00292 {
00293 ValidateState();
00294 return context;
00295 }
00296 private set { context = value; }
00297 }
00298
00299 #endregion
00300
00301 #region public float AspectRatio
00302
00306 [Description("The aspect ratio of the client area of this GLControl.")]
00307 public float AspectRatio
00308 {
00309 get
00310 {
00311 ValidateState();
00312 return ClientSize.Width / (float)ClientSize.Height;
00313 }
00314 }
00315
00316 #endregion
00317
00318 #region public bool VSync
00319
00323 [Description("Indicates whether GLControl updates are synced to the monitor's refresh.")]
00324 public bool VSync
00325 {
00326 get
00327 {
00328 if (!IsHandleCreated)
00329 return false;
00330
00331 ValidateState();
00332 return Context.VSync;
00333 }
00334 set
00335 {
00336
00337
00338
00339
00340 if (!IsHandleCreated)
00341 {
00342 initial_vsync_value = value;
00343 return;
00344 }
00345
00346 ValidateState();
00347 Context.VSync = value;
00348 }
00349 }
00350
00351 #endregion
00352
00353 #region public GraphicsMode GraphicsMode
00354
00361 public GraphicsMode GraphicsMode
00362 {
00363 get
00364 {
00365 ValidateState();
00366 return Context.GraphicsMode;
00367 }
00368 }
00369
00370 #endregion
00371
00372 #region WindowInfo
00373
00377 public IWindowInfo WindowInfo
00378 {
00379 get { return implementation.WindowInfo; }
00380 }
00381
00382 #endregion
00383
00384 #region public Bitmap GrabScreenshot()
00385
00391 [Obsolete("This method will not work correctly with OpenGL|ES. Please use GL.ReadPixels to capture the contents of the framebuffer (refer to http://www.opentk.com/doc/graphics/save-opengl-rendering-to-disk for more information).")]
00392 public Bitmap GrabScreenshot()
00393 {
00394 ValidateState();
00395
00396 Bitmap bmp = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
00397 System.Drawing.Imaging.BitmapData data =
00398 bmp.LockBits(this.ClientRectangle, System.Drawing.Imaging.ImageLockMode.WriteOnly,
00399 System.Drawing.Imaging.PixelFormat.Format24bppRgb);
00400 GL.ReadPixels(0, 0, this.ClientSize.Width, this.ClientSize.Height, PixelFormat.Bgr, PixelType.UnsignedByte,
00401 data.Scan0);
00402 bmp.UnlockBits(data);
00403 bmp.RotateFlip(RotateFlipType.RotateNoneFlipY);
00404 return bmp;
00405 }
00406
00407 #endregion
00408
00409 #endregion
00410 }
00411 }