Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 1452 | chris | 1 | #region --- License --- |
| 2 | /* Licensed under the MIT/X11 license. |
||
| 3 | * Copyright (c) 2006-2008 the OpenTK Team. |
||
| 4 | * This notice may not be removed from any source distribution. |
||
| 5 | * See license.txt for licensing detailed licensing details. |
||
| 6 | */ |
||
| 7 | #endregion |
||
| 8 | |||
| 9 | using System; |
||
| 10 | using System.Collections.Generic; |
||
| 11 | using System.Text; |
||
| 12 | using System.Diagnostics; |
||
| 13 | |||
| 14 | using OpenTK.Platform; |
||
| 15 | |||
| 16 | namespace OpenTK.Graphics |
||
| 17 | { |
||
| 18 | /// <summary> |
||
| 19 | /// Represents and provides methods to manipulate an OpenGL render context. |
||
| 20 | /// </summary> |
||
| 21 | public sealed class GraphicsContext : IGraphicsContext, IGraphicsContextInternal |
||
| 22 | { |
||
| 23 | #region --- Fields --- |
||
| 24 | |||
| 25 | IGraphicsContext implementation; // The actual render context implementation for the underlying platform. |
||
| 26 | bool disposed; |
||
| 27 | // Indicates that this context was created through external means, e.g. Tao.Sdl or GLWidget#. |
||
| 28 | // In this case, We'll assume that the external program will manage the lifetime of this |
||
| 29 | // context - we'll not destroy it manually. |
||
| 30 | readonly bool IsExternal; |
||
| 31 | bool check_errors = true; |
||
| 32 | |||
| 33 | static bool share_contexts = true; |
||
| 34 | static bool direct_rendering = true; |
||
| 35 | readonly static object SyncRoot = new object(); |
||
| 36 | // Maps OS-specific context handles to GraphicsContext weak references. |
||
| 37 | readonly static Dictionary<ContextHandle, WeakReference> available_contexts = new Dictionary<ContextHandle, WeakReference>(); |
||
| 38 | |||
| 39 | #endregion |
||
| 40 | |||
| 41 | #region --- Constructors --- |
||
| 42 | |||
| 43 | // Necessary to allow creation of dummy GraphicsContexts (see CreateDummyContext static method). |
||
| 44 | GraphicsContext(ContextHandle handle) |
||
| 45 | { |
||
| 46 | implementation = new OpenTK.Platform.Dummy.DummyGLContext(handle); |
||
| 47 | |||
| 48 | lock (SyncRoot) |
||
| 49 | { |
||
| 50 | available_contexts.Add((implementation as IGraphicsContextInternal).Context, new WeakReference(this)); |
||
| 51 | } |
||
| 52 | } |
||
| 53 | |||
| 54 | /// <summary> |
||
| 55 | /// Constructs a new GraphicsContext with the specified GraphicsMode and attaches it to the specified window. |
||
| 56 | /// </summary> |
||
| 57 | /// <param name="mode">The OpenTK.Graphics.GraphicsMode of the GraphicsContext.</param> |
||
| 58 | /// <param name="window">The OpenTK.Platform.IWindowInfo to attach the GraphicsContext to.</param> |
||
| 59 | public GraphicsContext(GraphicsMode mode, IWindowInfo window) |
||
| 60 | : this(mode, window, 1, 0, GraphicsContextFlags.Default) |
||
| 61 | { } |
||
| 62 | |||
| 63 | /// <summary> |
||
| 64 | /// Constructs a new GraphicsContext with the specified GraphicsMode, version and flags, and attaches it to the specified window. |
||
| 65 | /// </summary> |
||
| 66 | /// <param name="mode">The OpenTK.Graphics.GraphicsMode of the GraphicsContext.</param> |
||
| 67 | /// <param name="window">The OpenTK.Platform.IWindowInfo to attach the GraphicsContext to.</param> |
||
| 68 | /// <param name="major">The major version of the new GraphicsContext.</param> |
||
| 69 | /// <param name="minor">The minor version of the new GraphicsContext.</param> |
||
| 70 | /// <param name="flags">The GraphicsContextFlags for the GraphicsContext.</param> |
||
| 71 | /// <remarks> |
||
| 72 | /// Different hardware supports different flags, major and minor versions. Invalid parameters will be silently ignored. |
||
| 73 | /// </remarks> |
||
| 74 | public GraphicsContext(GraphicsMode mode, IWindowInfo window, int major, int minor, GraphicsContextFlags flags) |
||
| 75 | { |
||
| 76 | lock (SyncRoot) |
||
| 77 | { |
||
| 78 | bool designMode = false; |
||
| 79 | if (mode == null && window == null) |
||
| 80 | designMode = true; |
||
| 81 | else if (mode == null) throw new ArgumentNullException("mode", "Must be a valid GraphicsMode."); |
||
| 82 | else if (window == null) throw new ArgumentNullException("window", "Must point to a valid window."); |
||
| 83 | |||
| 84 | // Silently ignore invalid major and minor versions. |
||
| 85 | if (major <= 0) |
||
| 86 | major = 1; |
||
| 87 | if (minor < 0) |
||
| 88 | minor = 0; |
||
| 89 | |||
| 90 | Debug.Print("Creating GraphicsContext."); |
||
| 91 | try |
||
| 92 | { |
||
| 93 | Debug.Indent(); |
||
| 94 | Debug.Print("GraphicsMode: {0}", mode); |
||
| 95 | Debug.Print("IWindowInfo: {0}", window); |
||
| 96 | Debug.Print("GraphicsContextFlags: {0}", flags); |
||
| 97 | Debug.Print("Requested version: {0}.{1}", major, minor); |
||
| 98 | |||
| 99 | IGraphicsContext shareContext = shareContext = FindSharedContext(); |
||
| 100 | |||
| 101 | // Todo: Add a DummyFactory implementing IPlatformFactory. |
||
| 102 | if (designMode) |
||
| 103 | { |
||
| 104 | implementation = new Platform.Dummy.DummyGLContext(); |
||
| 105 | } |
||
| 106 | else |
||
| 107 | { |
||
| 108 | IPlatformFactory factory = null; |
||
| 109 | switch ((flags & GraphicsContextFlags.Embedded) == GraphicsContextFlags.Embedded) |
||
| 110 | { |
||
| 111 | case false: factory = Factory.Default; break; |
||
| 112 | case true: factory = Factory.Embedded; break; |
||
| 113 | } |
||
| 114 | |||
| 115 | implementation = factory.CreateGLContext(mode, window, shareContext, direct_rendering, major, minor, flags); |
||
| 116 | // Note: this approach does not allow us to mix native and EGL contexts in the same process. |
||
| 117 | // This should not be a problem, as this use-case is not interesting for regular applications. |
||
| 118 | // Note 2: some platforms may not support a direct way of getting the current context |
||
| 119 | // (this happens e.g. with DummyGLContext). In that case, we use a slow fallback which |
||
| 120 | // iterates through all known contexts and checks if any is current (check GetCurrentContext |
||
| 121 | // declaration). |
||
| 122 | if (GetCurrentContext == null) |
||
| 123 | { |
||
| 124 | GetCurrentContextDelegate temp = factory.CreateGetCurrentGraphicsContext(); |
||
| 125 | if (temp != null) |
||
| 126 | { |
||
| 127 | GetCurrentContext = temp; |
||
| 128 | } |
||
| 129 | } |
||
| 130 | } |
||
| 131 | |||
| 132 | available_contexts.Add((this as IGraphicsContextInternal).Context, new WeakReference(this)); |
||
| 133 | } |
||
| 134 | finally |
||
| 135 | { |
||
| 136 | Debug.Unindent(); |
||
| 137 | } |
||
| 138 | } |
||
| 139 | } |
||
| 140 | |||
| 141 | /// <summary> |
||
| 142 | /// Constructs a new GraphicsContext from a pre-existing context created outside of OpenTK. |
||
| 143 | /// </summary> |
||
| 144 | /// <param name="handle">The handle of the existing context. This must be a valid, unique handle that is not known to OpenTK.</param> |
||
| 145 | /// <param name="window">The window this context is bound to. This must be a valid window obtained through Utilities.CreateWindowInfo.</param> |
||
| 146 | /// <exception cref="GraphicsContextException">Occurs if handle is identical to a context already registered with OpenTK.</exception> |
||
| 147 | public GraphicsContext(ContextHandle handle, IWindowInfo window) |
||
| 148 | : this(handle, window, null, 1, 0, GraphicsContextFlags.Default) |
||
| 149 | { } |
||
| 150 | |||
| 151 | /// <summary> |
||
| 152 | /// Constructs a new GraphicsContext from a pre-existing context created outside of OpenTK. |
||
| 153 | /// </summary> |
||
| 154 | /// <param name="handle">The handle of the existing context. This must be a valid, unique handle that is not known to OpenTK.</param> |
||
| 155 | /// <param name="window">The window this context is bound to. This must be a valid window obtained through Utilities.CreateWindowInfo.</param> |
||
| 156 | /// <param name="shareContext">A different context that shares resources with this instance, if any. |
||
| 157 | /// Pass null if the context is not shared or if this is the first GraphicsContext instruct you construct.</param> |
||
| 158 | /// <param name="major">The major version of the context (e.g. "2" for "2.1").</param> |
||
| 159 | /// <param name="minor">The minor version of the context (e.g. "1" for "2.1").</param> |
||
| 160 | /// <param name="flags">A bitwise combination of <see cref="GraphicsContextFlags"/> that describe this context.</param> |
||
| 161 | /// <exception cref="GraphicsContextException">Occurs if handle is identical to a context already registered with OpenTK.</exception> |
||
| 162 | public GraphicsContext(ContextHandle handle, IWindowInfo window, IGraphicsContext shareContext, int major, int minor, GraphicsContextFlags flags) |
||
| 163 | { |
||
| 164 | lock (SyncRoot) |
||
| 165 | { |
||
| 166 | IsExternal = true; |
||
| 167 | |||
| 168 | if (handle == ContextHandle.Zero) |
||
| 169 | { |
||
| 170 | implementation = new OpenTK.Platform.Dummy.DummyGLContext(handle); |
||
| 171 | } |
||
| 172 | else if (available_contexts.ContainsKey(handle)) |
||
| 173 | { |
||
| 174 | throw new GraphicsContextException("Context already exists."); |
||
| 175 | } |
||
| 176 | else |
||
| 177 | { |
||
| 178 | switch ((flags & GraphicsContextFlags.Embedded) == GraphicsContextFlags.Embedded) |
||
| 179 | { |
||
| 180 | case false: implementation = Factory.Default.CreateGLContext(handle, window, shareContext, direct_rendering, major, minor, flags); break; |
||
| 181 | case true: implementation = Factory.Embedded.CreateGLContext(handle, window, shareContext, direct_rendering, major, minor, flags); break; |
||
| 182 | } |
||
| 183 | } |
||
| 184 | |||
| 185 | available_contexts.Add((implementation as IGraphicsContextInternal).Context, new WeakReference(this)); |
||
| 186 | |||
| 187 | (this as IGraphicsContextInternal).LoadAll(); |
||
| 188 | } |
||
| 189 | } |
||
| 190 | |||
| 191 | #endregion |
||
| 192 | |||
| 193 | #region Private Members |
||
| 194 | |||
| 195 | static IGraphicsContext FindSharedContext() |
||
| 196 | { |
||
| 197 | if (GraphicsContext.ShareContexts) |
||
| 198 | { |
||
| 199 | // A small hack to create a shared context with the first available context. |
||
| 200 | foreach (WeakReference r in GraphicsContext.available_contexts.Values) |
||
| 201 | { |
||
| 202 | // Fix for bug 1874: if a GraphicsContext gets finalized |
||
| 203 | // (but not disposed), it won't be removed from available_contexts |
||
| 204 | // making this return null even if another valid context exists. |
||
| 205 | // The workaround is to simply ignore null targets. |
||
| 206 | IGraphicsContext target = r.Target as IGraphicsContext; |
||
| 207 | if (target != null) |
||
| 208 | return target; |
||
| 209 | } |
||
| 210 | } |
||
| 211 | return null; |
||
| 212 | } |
||
| 213 | |||
| 214 | #endregion |
||
| 215 | |||
| 216 | #region --- Static Members --- |
||
| 217 | |||
| 218 | #region public static GraphicsContext CreateDummyContext() |
||
| 219 | |||
| 220 | /// <summary> |
||
| 221 | /// Creates a dummy GraphicsContext to allow OpenTK to work with contexts created by external libraries. |
||
| 222 | /// </summary> |
||
| 223 | /// <returns>A new, dummy GraphicsContext instance.</returns> |
||
| 224 | /// <remarks> |
||
| 225 | /// <para>Instances created by this method will not be functional. Instance methods will have no effect.</para> |
||
| 226 | /// <para>This method requires that a context is current on the calling thread.</para> |
||
| 227 | /// </remarks> |
||
| 228 | public static GraphicsContext CreateDummyContext() |
||
| 229 | { |
||
| 230 | ContextHandle handle = GetCurrentContext(); |
||
| 231 | if (handle == ContextHandle.Zero) |
||
| 232 | throw new InvalidOperationException("No GraphicsContext is current on the calling thread."); |
||
| 233 | |||
| 234 | return CreateDummyContext(handle); |
||
| 235 | } |
||
| 236 | |||
| 237 | /// <summary> |
||
| 238 | /// Creates a dummy GraphicsContext to allow OpenTK to work with contexts created by external libraries. |
||
| 239 | /// </summary> |
||
| 240 | /// <param name="handle">The handle of a context.</param> |
||
| 241 | /// <returns>A new, dummy GraphicsContext instance.</returns> |
||
| 242 | /// <remarks> |
||
| 243 | /// <para>Instances created by this method will not be functional. Instance methods will have no effect.</para> |
||
| 244 | /// </remarks> |
||
| 245 | public static GraphicsContext CreateDummyContext(ContextHandle handle) |
||
| 246 | { |
||
| 247 | if (handle == ContextHandle.Zero) |
||
| 248 | throw new ArgumentOutOfRangeException("handle"); |
||
| 249 | |||
| 250 | return new GraphicsContext(handle); |
||
| 251 | } |
||
| 252 | |||
| 253 | #endregion |
||
| 254 | |||
| 255 | #region public static void Assert() |
||
| 256 | |||
| 257 | /// <summary> |
||
| 258 | /// Checks if a GraphicsContext exists in the calling thread and throws a GraphicsContextMissingException if it doesn't. |
||
| 259 | /// </summary> |
||
| 260 | /// <exception cref="GraphicsContextMissingException">Generated when no GraphicsContext is current in the calling thread.</exception> |
||
| 261 | public static void Assert() |
||
| 262 | { |
||
| 263 | if (GraphicsContext.CurrentContext == null) |
||
| 264 | throw new GraphicsContextMissingException(); |
||
| 265 | } |
||
| 266 | |||
| 267 | #endregion |
||
| 268 | |||
| 269 | #region public static IGraphicsContext CurrentContext |
||
| 270 | |||
| 271 | internal delegate ContextHandle GetCurrentContextDelegate(); |
||
| 272 | internal static GetCurrentContextDelegate GetCurrentContext = delegate |
||
| 273 | { |
||
| 274 | // Note: this is a slow, generic fallback for use with DummyGLContext. |
||
| 275 | // Most other platforms can query the current context directly (via |
||
| 276 | // [Wgl|Glx|Agl|Egl].GetCurrentContext()) so the GraphicsContext |
||
| 277 | // constructor will replace this implementation with a platform-specific |
||
| 278 | // one, if it exists. |
||
| 279 | foreach (WeakReference weak_ref in available_contexts.Values) |
||
| 280 | { |
||
| 281 | IGraphicsContext context = (IGraphicsContext)weak_ref.Target; |
||
| 282 | if (context.IsCurrent) |
||
| 283 | { |
||
| 284 | return (context as IGraphicsContextInternal).Context; |
||
| 285 | } |
||
| 286 | } |
||
| 287 | |||
| 288 | return ContextHandle.Zero; |
||
| 289 | }; |
||
| 290 | |||
| 291 | /// <summary> |
||
| 292 | /// Gets the GraphicsContext that is current in the calling thread. |
||
| 293 | /// </summary> |
||
| 294 | /// <remarks> |
||
| 295 | /// Note: this property will not function correctly when both desktop and EGL contexts are |
||
| 296 | /// available in the same process. This scenario is very unlikely to appear in practice. |
||
| 297 | /// </remarks> |
||
| 298 | public static IGraphicsContext CurrentContext |
||
| 299 | { |
||
| 300 | get |
||
| 301 | { |
||
| 302 | lock (SyncRoot) |
||
| 303 | { |
||
| 304 | if (available_contexts.Count > 0) |
||
| 305 | { |
||
| 306 | ContextHandle handle = GetCurrentContext(); |
||
| 307 | if (handle.Handle != IntPtr.Zero) |
||
| 308 | return (GraphicsContext)available_contexts[handle].Target; |
||
| 309 | } |
||
| 310 | return null; |
||
| 311 | } |
||
| 312 | } |
||
| 313 | } |
||
| 314 | |||
| 315 | #endregion |
||
| 316 | |||
| 317 | #region public static bool ShareContexts |
||
| 318 | |||
| 319 | /// <summary>Gets or sets a System.Boolean, indicating whether GraphicsContext resources are shared</summary> |
||
| 320 | /// <remarks> |
||
| 321 | /// <para>If ShareContexts is true, new GLContexts will share resources. If this value is |
||
| 322 | /// false, new GLContexts will not share resources.</para> |
||
| 323 | /// <para>Changing this value will not affect already created GLContexts.</para> |
||
| 324 | /// </remarks> |
||
| 325 | public static bool ShareContexts { get { return share_contexts; } set { share_contexts = value; } } |
||
| 326 | |||
| 327 | #endregion |
||
| 328 | |||
| 329 | #region public static bool DirectRendering |
||
| 330 | |||
| 331 | /// <summary>Gets or sets a System.Boolean, indicating whether GraphicsContexts will perform direct rendering.</summary> |
||
| 332 | /// <remarks> |
||
| 333 | /// <para> |
||
| 334 | /// If DirectRendering is true, new contexts will be constructed with direct rendering capabilities, if possible. |
||
| 335 | /// If DirectRendering is false, new contexts will be constructed with indirect rendering capabilities. |
||
| 336 | /// </para> |
||
| 337 | /// <para>This property does not affect existing GraphicsContexts, unless they are recreated.</para> |
||
| 338 | /// <para> |
||
| 339 | /// This property is ignored on Operating Systems without support for indirect rendering, like Windows and OS X. |
||
| 340 | /// </para> |
||
| 341 | /// </remarks> |
||
| 342 | public static bool DirectRendering |
||
| 343 | { |
||
| 344 | get { return direct_rendering; } |
||
| 345 | set { direct_rendering = value; } |
||
| 346 | } |
||
| 347 | |||
| 348 | #endregion |
||
| 349 | |||
| 350 | #endregion |
||
| 351 | |||
| 352 | #region --- IGraphicsContext Members --- |
||
| 353 | |||
| 354 | /// <summary> |
||
| 355 | /// Gets or sets a System.Boolean, indicating whether automatic error checking should be performed. |
||
| 356 | /// Influences the debug version of OpenTK.dll, only. |
||
| 357 | /// </summary> |
||
| 358 | /// <remarks>Automatic error checking will clear the OpenGL error state. Set CheckErrors to false if you use |
||
| 359 | /// the OpenGL error state in your code flow (e.g. for checking supported texture formats).</remarks> |
||
| 360 | public bool ErrorChecking |
||
| 361 | { |
||
| 362 | get { return check_errors; } |
||
| 363 | set { check_errors = value; } |
||
| 364 | } |
||
| 365 | /// <summary> |
||
| 366 | /// Creates an OpenGL context with the specified direct/indirect rendering mode and sharing state with the |
||
| 367 | /// specified IGraphicsContext. |
||
| 368 | /// </summary> |
||
| 369 | /// <param name="direct">Set to true for direct rendering or false otherwise.</param> |
||
| 370 | /// <param name="source">The source IGraphicsContext to share state from.</param>. |
||
| 371 | /// <remarks> |
||
| 372 | /// <para> |
||
| 373 | /// Direct rendering is the default rendering mode for OpenTK, since it can provide higher performance |
||
| 374 | /// in some circumastances. |
||
| 375 | /// </para> |
||
| 376 | /// <para> |
||
| 377 | /// The 'direct' parameter is a hint, and will ignored if the specified mode is not supported (e.g. setting |
||
| 378 | /// indirect rendering on Windows platforms). |
||
| 379 | /// </para> |
||
| 380 | /// </remarks> |
||
| 381 | void CreateContext(bool direct, IGraphicsContext source) |
||
| 382 | { |
||
| 383 | lock (SyncRoot) |
||
| 384 | { |
||
| 385 | available_contexts.Add((this as IGraphicsContextInternal).Context, new WeakReference(this)); |
||
| 386 | } |
||
| 387 | } |
||
| 388 | |||
| 389 | /// <summary> |
||
| 390 | /// Swaps buffers on a context. This presents the rendered scene to the user. |
||
| 391 | /// </summary> |
||
| 392 | public void SwapBuffers() |
||
| 393 | { |
||
| 394 | implementation.SwapBuffers(); |
||
| 395 | } |
||
| 396 | |||
| 397 | /// <summary> |
||
| 398 | /// Makes the GraphicsContext the current rendering target. |
||
| 399 | /// </summary> |
||
| 400 | /// <param name="window">A valid <see cref="OpenTK.Platform.IWindowInfo" /> structure.</param> |
||
| 401 | /// <remarks> |
||
| 402 | /// You can use this method to bind the GraphicsContext to a different window than the one it was created from. |
||
| 403 | /// </remarks> |
||
| 404 | public void MakeCurrent(IWindowInfo window) |
||
| 405 | { |
||
| 406 | implementation.MakeCurrent(window); |
||
| 407 | } |
||
| 408 | |||
| 409 | /// <summary> |
||
| 410 | /// Gets a <see cref="System.Boolean"/> indicating whether this instance is current in the calling thread. |
||
| 411 | /// </summary> |
||
| 412 | public bool IsCurrent |
||
| 413 | { |
||
| 414 | get { return implementation.IsCurrent; } |
||
| 415 | } |
||
| 416 | |||
| 417 | /// <summary> |
||
| 418 | /// Gets a <see cref="System.Boolean"/> indicating whether this instance has been disposed. |
||
| 419 | /// It is an error to access any instance methods if this property returns true. |
||
| 420 | /// </summary> |
||
| 421 | public bool IsDisposed |
||
| 422 | { |
||
| 423 | get { return disposed && implementation.IsDisposed; } |
||
| 424 | private set { disposed = value; } |
||
| 425 | } |
||
| 426 | |||
| 427 | /// <summary> |
||
| 428 | /// Gets or sets a value indicating whether VSync is enabled. |
||
| 429 | /// </summary> |
||
| 430 | public bool VSync |
||
| 431 | { |
||
| 432 | get { return implementation.VSync; } |
||
| 433 | set { implementation.VSync = value; } |
||
| 434 | } |
||
| 435 | |||
| 436 | /// <summary> |
||
| 437 | /// Updates the graphics context. This must be called when the render target |
||
| 438 | /// is resized for proper behavior on Mac OS X. |
||
| 439 | /// </summary> |
||
| 440 | /// <param name="window"></param> |
||
| 441 | public void Update(IWindowInfo window) |
||
| 442 | { |
||
| 443 | implementation.Update(window); |
||
| 444 | } |
||
| 445 | |||
| 446 | /// <summary> |
||
| 447 | /// Loads all OpenGL entry points. |
||
| 448 | /// </summary> |
||
| 449 | /// <exception cref="OpenTK.Graphics.GraphicsContextException"> |
||
| 450 | /// Occurs when this instance is not current on the calling thread. |
||
| 451 | /// </exception> |
||
| 452 | public void LoadAll() |
||
| 453 | { |
||
| 454 | if (GraphicsContext.CurrentContext != this) |
||
| 455 | throw new GraphicsContextException(); |
||
| 456 | |||
| 457 | implementation.LoadAll(); |
||
| 458 | } |
||
| 459 | |||
| 460 | #endregion |
||
| 461 | |||
| 462 | #region --- IGraphicsContextInternal Members --- |
||
| 463 | |||
| 464 | /// <summary> |
||
| 465 | /// Gets the platform-specific implementation of this IGraphicsContext. |
||
| 466 | /// </summary> |
||
| 467 | IGraphicsContext IGraphicsContextInternal.Implementation |
||
| 468 | { |
||
| 469 | get { return implementation; } |
||
| 470 | } |
||
| 471 | |||
| 472 | /// <summary> |
||
| 473 | /// Gets a handle to the OpenGL rendering context. |
||
| 474 | /// </summary> |
||
| 475 | ContextHandle IGraphicsContextInternal.Context |
||
| 476 | { |
||
| 477 | get { return ((IGraphicsContextInternal)implementation).Context; } |
||
| 478 | } |
||
| 479 | |||
| 480 | /// <summary> |
||
| 481 | /// Gets the GraphicsMode of the context. |
||
| 482 | /// </summary> |
||
| 483 | public GraphicsMode GraphicsMode |
||
| 484 | { |
||
| 485 | get { return (implementation as IGraphicsContext).GraphicsMode; } |
||
| 486 | } |
||
| 487 | |||
| 488 | /// <summary> |
||
| 489 | /// Gets the address of an OpenGL extension function. |
||
| 490 | /// </summary> |
||
| 491 | /// <param name="function">The name of the OpenGL function (e.g. "glGetString")</param> |
||
| 492 | /// <returns> |
||
| 493 | /// A pointer to the specified function or IntPtr.Zero if the function isn't |
||
| 494 | /// available in the current opengl context. |
||
| 495 | /// </returns> |
||
| 496 | IntPtr IGraphicsContextInternal.GetAddress(string function) |
||
| 497 | { |
||
| 498 | return (implementation as IGraphicsContextInternal).GetAddress(function); |
||
| 499 | } |
||
| 500 | |||
| 501 | #endregion |
||
| 502 | |||
| 503 | #region --- IDisposable Members --- |
||
| 504 | |||
| 505 | /// <summary> |
||
| 506 | /// Disposes of the GraphicsContext. |
||
| 507 | /// </summary> |
||
| 508 | public void Dispose() |
||
| 509 | { |
||
| 510 | this.Dispose(true); |
||
| 511 | GC.SuppressFinalize(this); |
||
| 512 | } |
||
| 513 | |||
| 514 | void Dispose(bool manual) |
||
| 515 | { |
||
| 516 | if (!IsDisposed) |
||
| 517 | { |
||
| 518 | Debug.Print("Disposing context {0}.", (this as IGraphicsContextInternal).Context.ToString()); |
||
| 519 | lock (SyncRoot) |
||
| 520 | { |
||
| 521 | available_contexts.Remove((this as IGraphicsContextInternal).Context); |
||
| 522 | } |
||
| 523 | |||
| 524 | if (manual && !IsExternal) |
||
| 525 | { |
||
| 526 | if (implementation != null) |
||
| 527 | implementation.Dispose(); |
||
| 528 | } |
||
| 529 | IsDisposed = true; |
||
| 530 | } |
||
| 531 | } |
||
| 532 | |||
| 533 | #endregion |
||
| 534 | } |
||
| 535 | } |