Added the capability to specify the desired OpenGL version and parameters (debug / forward-compatible context).

Added OpenGL 3.0 support for GLX contexts.
Added support for creating dummy contexts (useful if you are creating contexts from an external library).
Cleaned up unused and stale code.
This commit is contained in:
the_fiddler 2009-03-07 10:36:51 +00:00
parent 4cfaaf6077
commit 4a2a223751
16 changed files with 356 additions and 172 deletions

View file

@ -20,6 +20,8 @@ namespace OpenTK.Graphics
/// </summary>
public sealed class GraphicsContext : IGraphicsContext, IGraphicsContextInternal
{
#region --- Fields ---
IGraphicsContext implementation; // The actual render context implementation for the underlying platform.
List<IDisposable> dispose_queue = new List<IDisposable>();
bool disposed;
@ -30,18 +32,38 @@ namespace OpenTK.Graphics
static bool share_contexts = true;
static bool direct_rendering = true;
static object context_lock = new object();
readonly static object context_lock = new object();
// Maps OS-specific context handles to GraphicsContext weak references.
static Dictionary<ContextHandle, WeakReference> available_contexts = new Dictionary<ContextHandle, WeakReference>();
readonly static Dictionary<ContextHandle, WeakReference> available_contexts = new Dictionary<ContextHandle, WeakReference>();
#region public GraphicsContext(GraphicsMode format, IWindowInfo window)
#endregion
#region --- Constructors ---
// Necessary to allow creation of dummy GraphicsContexts (see CreateDummyContext static method).
GraphicsContext() { }
/// <summary>
/// Constructs a new GraphicsContext with the specified format, and attaches it to the specified window.
/// Constructs a new GraphicsContext with the specified GraphicsMode and attaches it to the specified window.
/// </summary>
/// <param name="format">The OpenTK.Graphics.GraphicsMode of the GraphicsContext.</param>
/// <param name="window">The OpenTK.Platform.IWindowInfo to attach the GraphicsContext to.</param>
public GraphicsContext(GraphicsMode mode, IWindowInfo window)
: this(mode, window, 1, 0, GraphicsContextFlags.Default)
{ }
/// <summary>
/// Constructs a new GraphicsContext with the specified GraphicsMode, version and flags, and attaches it to the specified window.
/// </summary>
/// <param name="format">The OpenTK.Graphics.GraphicsMode of the GraphicsContext.</param>
/// <param name="window">The OpenTK.Platform.IWindowInfo to attach the GraphicsContext to.</param>
/// <param name="major">The major version of the new GraphicsContext.</param>
/// <param name="minor">The minor version of the new GraphicsContext.</param>
/// <param name="flags">The GraphicsContextFlags for the GraphicsContext.</param>
/// <remarks>
/// Different hardware supports different flags, major and minor versions. Invalid parameters will be silently ignored.
/// </remarks>
public GraphicsContext(GraphicsMode mode, IWindowInfo window, int major, int minor, GraphicsContextFlags flags)
{
bool designMode = false;
if (mode == null && window == null)
@ -49,6 +71,12 @@ namespace OpenTK.Graphics
else if (mode == null) throw new ArgumentNullException("mode", "Must be a valid GraphicsMode.");
else if (window == null) throw new ArgumentNullException("window", "Must point to a valid window.");
// Silently ignore invalid major and minor versions.
if (major <= 0)
major = 1;
if (minor < 0)
minor = 0;
Debug.Print("Creating GraphicsContext.");
try
{
@ -70,10 +98,11 @@ namespace OpenTK.Graphics
}
}
// Todo: Add a DummyFactory implementing IPlatformFactory.
if (designMode)
implementation = new Platform.Dummy.DummyGLContext(mode);
else
implementation = Factory.CreateGLContext(mode, window, shareContext, DirectRendering);
implementation = Factory.CreateGLContext(mode, window, shareContext, DirectRendering, major, minor, flags);
lock (context_lock)
{
@ -89,36 +118,20 @@ namespace OpenTK.Graphics
#endregion
#region private GraphicsContext()
private GraphicsContext()
{ }
#endregion
#region --- Static Members ---
/// <summary>
/// Attempts to create a GraphicsContext object from an existing OpenGL context.
/// Creates a dummy GraphicsContext to allow OpenTK to work with contexts created by external libraries.
/// </summary>
/// <param name="window">The window this context is bound to.</param>
/// <returns>A new GraphicsContext object, describing the current OpenGL context.</returns>
/// <returns>A new, dummy GraphicsContext instance.</returns>
/// <remarks>
/// <para>Use this function to interoperate with OpenGL contexts created outside of OpenTK.</para>
/// <para>The new GraphicsContext is added to the list of available OpenTK contexts.
/// Make sure to call the Dispose() method once this context is destroyed.</para>
/// <para>You may not call this method more than once on the same context. Doing so will throw an exception.</para>
/// <para>Instances created by this methodwill not be functional. Instance methods will have no effect.</para>
/// </remarks>
public static GraphicsContext CreateFromCurrentThread(IWindowInfo window)
public static GraphicsContext CreateDummyContext()
{
Debug.Print("Creating context from current thread.");
GraphicsContext context = new GraphicsContext();
context.is_external = true;
if (Configuration.RunningOnWindows)
context.implementation = new OpenTK.Platform.Windows.WinGLContext(window);
else if (Configuration.RunningOnX11)
context.implementation = new OpenTK.Platform.X11.X11GLContext(window);
else
throw new PlatformNotSupportedException("Please, refer to http://www.opentk.com for more information.");
context.implementation = new OpenTK.Platform.Dummy.DummyGLContext(GraphicsMode.Default);
lock (context_lock)
{
@ -128,6 +141,10 @@ namespace OpenTK.Graphics
return context;
}
#endregion
#region --- Private Members ---
#region void ContextDestroyed(IGraphicsContext context, EventArgs e)
/// <summary>
@ -143,6 +160,8 @@ namespace OpenTK.Graphics
#endregion
#endregion
#region --- Public Members ---
#region public static IGraphicsContext CurrentContext
@ -232,10 +251,6 @@ namespace OpenTK.Graphics
#endregion
internal IGraphicsContext Implementation
{
get { return implementation; }
}
#region --- IGraphicsContext Members ---
/// <summary>
@ -329,6 +344,15 @@ namespace OpenTK.Graphics
#region --- IGraphicsContextInternal Members ---
#region Implementation
IGraphicsContext IGraphicsContextInternal.Implementation
{
get { return implementation; }
}
#endregion
#region void LoadAll()
void IGraphicsContextInternal.LoadAll()

View file

@ -0,0 +1,57 @@
#region License
//
// The Open Toolkit Library License
//
// Copyright (c) 2006 - 2008 the Open Toolkit library, except where noted.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
#endregion
using System;
using System.Collections.Generic;
using System.Text;
namespace OpenTK.Graphics
{
/// <summary>
/// Enumerates various flags that affect the creation of new GraphicsContexts.
/// </summary>
[Flags]
public enum GraphicsContextFlags
{
/// <summary>
/// The default value of the GraphicsContextFlags enumeration.
/// </summary>
Default = 0x0000,
/// <summary>
/// Indicates that this is a debug GraphicsContext. Debug contexts may provide
/// additional debugging information at the cost of performance.
/// </summary>
/// <remarks></remarks>
Debug = 0x0001,
/// <summary>
/// Indicates that this is a forward compatible GraphicsContext. Forward-compatible contexts
/// do not support functionality marked as deprecated in the current GraphicsContextVersion.
/// </summary>
/// <remarks>Forward-compatible contexts are defined only for OpenGL versions 3.0 and later.</remarks>
ForwardCompatible = 0x0002
}
}

View file

@ -0,0 +1,82 @@
#region License
//
// The Open Toolkit Library License
//
// Copyright (c) 2006 - 2008 the Open Toolkit library, except where noted.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
#endregion
using System;
using System.Collections.Generic;
using System.Text;
namespace OpenTK.Graphics
{
/// <summary>
/// Defines the version information of a GraphicsContext.
/// </summary>
public sealed class GraphicsContextVersion
{
#region Fields
int minor, major;
string vendor = String.Empty, renderer = String.Empty;
#endregion
#region Constructors
internal GraphicsContextVersion(int minor, int major, string vendor, string renderer)
{
Minor = minor;
Major = major;
Vendor = vendor;
Renderer = renderer;
}
#endregion
#region Public Members
/// <summary>
/// Gets a System.Int32 indicating the minor version of a GraphicsContext instance.
/// </summary>
public int Minor { get { return minor; } private set { minor = value; } }
/// <summary>
/// Gets a System.Int32 indicating the major version of a GraphicsContext instance.
/// </summary>
public int Major { get { return major; } private set { major = value; } }
/// <summary>
/// Gets a System.String indicating the vendor of a GraphicsContext instance.
/// </summary>
public string Vendor { get { return vendor; } private set { vendor = value; } }
/// <summary>
/// Gets a System.String indicating the renderer of a GraphicsContext instance.
/// </summary>
public string Renderer { get { return renderer; } private set { renderer = value; } }
#endregion
}
}

View file

@ -63,6 +63,8 @@ namespace OpenTK.Graphics
/// </summary>
public interface IGraphicsContextInternal
{
IGraphicsContext Implementation { get; }
///// <summary>
///// Creates an OpenGL context with the specified direct/indirect rendering mode and sharing state with the
///// specified IGraphicsContext.
@ -80,9 +82,9 @@ namespace OpenTK.Graphics
/// </summary>
ContextHandle Context { get; }
/// <summary>
/// Gets the IWindowInfo describing the window associated with this context.
/// </summary>
// <summary>
// Gets the IWindowInfo describing the window associated with this context.
// </summary>
//IWindowInfo Info { get; }
/// <summary>Gets the GraphicsMode of the context.</summary>

View file

@ -81,7 +81,12 @@ namespace OpenTK.Platform.Dummy
#region IGraphicsContextInternal Members
public void LoadAll()
IGraphicsContext IGraphicsContextInternal.Implementation
{
get { return this; }
}
void IGraphicsContextInternal.LoadAll()
{
}
@ -91,6 +96,5 @@ namespace OpenTK.Platform.Dummy
}
#endregion
}
}

View file

@ -33,9 +33,9 @@ namespace OpenTK.Platform
return implementation.CreateDisplayDeviceDriver();
}
internal static IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool directRendering)
internal static IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
{
return implementation.CreateGLContext(mode, window, shareContext, directRendering);
return implementation.CreateGLContext(mode, window, shareContext, directRendering, major, minor, flags);
}
internal static IGraphicsMode CreateGraphicsMode()
@ -62,7 +62,7 @@ namespace OpenTK.Platform
throw new PlatformNotSupportedException("Please, refer to http://www.opentk.com for more information.");
}
public IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool DirectRendering)
public IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool DirectRendering, int major, int minor, GraphicsContextFlags flags)
{
throw new PlatformNotSupportedException("Please, refer to http://www.opentk.com for more information.");
}

View file

@ -12,7 +12,7 @@ namespace OpenTK.Platform
OpenTK.Graphics.IDisplayDeviceDriver CreateDisplayDeviceDriver();
OpenTK.Graphics.IGraphicsContext CreateGLContext(OpenTK.Graphics.GraphicsMode mode, IWindowInfo window, OpenTK.Graphics.IGraphicsContext shareContext, bool DirectRendering);
OpenTK.Graphics.IGraphicsContext CreateGLContext(OpenTK.Graphics.GraphicsMode mode, IWindowInfo window, OpenTK.Graphics.IGraphicsContext shareContext, bool DirectRendering, int major, int minor, OpenTK.Graphics.GraphicsContextFlags flags);
OpenTK.Graphics.IGraphicsMode CreateGraphicsMode();
}

View file

@ -389,6 +389,11 @@ namespace OpenTK.Platform.MacOS
#region IGraphicsContextInternal Members
IGraphicsContext IGraphicsContextInternal.Implementation
{
get { return this; }
}
void IGraphicsContextInternal.LoadAll()
{
GL.LoadAll();
@ -421,6 +426,5 @@ namespace OpenTK.Platform.MacOS
}
#endregion
}
}

View file

@ -728,7 +728,7 @@ namespace OpenTK.Platform.MacOS
private void SetFullscreen()
{
((AglContext)context.Implementation).SetFullScreen(window);
((AglContext)(context as IGraphicsContextInternal).Implementation).SetFullScreen(window);
mWindowedWidth = mWidth;
mWindowedHeight = mHeight;
@ -743,7 +743,7 @@ namespace OpenTK.Platform.MacOS
}
private void UnsetFullscreen()
{
((AglContext)context.Implementation).UnsetFullScreen(window);
((AglContext)(context as IGraphicsContextInternal).Implementation).UnsetFullScreen(window);
SetSize(mWindowedWidth, mWindowedHeight);
}

View file

@ -25,7 +25,7 @@ namespace OpenTK.Platform.MacOS
return new QuartzDisplayDeviceDriver();
}
public IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool DirectRendering)
public IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool DirectRendering, int major, int minor, GraphicsContextFlags flags)
{
return new AglContext(mode, window, shareContext);
}

View file

@ -26,9 +26,9 @@ using OpenTK.Input;
return new WinDisplayDeviceDriver();
}
public IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool directRendering)
public IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool directRendering, int major, int minor, GraphicsContextFlags flags)
{
return new WinGLContext(mode, window, shareContext);
return new WinGLContext(mode, window, shareContext, major, minor, flags);
}
public IGraphicsMode CreateGraphicsMode()

View file

@ -59,7 +59,8 @@ namespace OpenTK.Platform.Windows
}
}
public WinGLContext(GraphicsMode format, IWindowInfo window, IGraphicsContext sharedContext)
public WinGLContext(GraphicsMode format, IWindowInfo window, IGraphicsContext sharedContext,
int major, int minor, GraphicsContextFlags flags)
{
if (window == null)
throw new ArgumentNullException("window", "Must point to a valid window.");
@ -91,17 +92,24 @@ namespace OpenTK.Platform.Windows
{
try
{
Debug.Write("Attempting to create GL3 render context... ");
Debug.WriteLine("Using WGL_ARB_create_context...");
List<int> attributes = new List<int>();
attributes.Add((int)ArbCreateContext.MajorVersion);
attributes.Add(major);
attributes.Add((int)ArbCreateContext.MinorVersion);
attributes.Add(minor);
if (flags != 0)
{
attributes.Add((int)ArbCreateContext.Flags);
attributes.Add((int)flags);
}
renderContext = new ContextHandle(
Wgl.Arb.CreateContextAttribs(
currentWindow.DeviceContext,
sharedContext != null ? (sharedContext as IGraphicsContextInternal).Context.Handle : IntPtr.Zero,
new int[]
{
(int)ArbCreateContext.MajorVersion, 3,
(int)ArbCreateContext.MinorVersion, 0,
0
}));
attributes.ToArray()));
}
catch (EntryPointNotFoundException e) { Debug.Print(e.ToString()); }
catch (NullReferenceException e) { Debug.Print(e.ToString()); }
@ -129,50 +137,10 @@ namespace OpenTK.Platform.Windows
}
}
public WinGLContext(IWindowInfo window)
{
if (window == null) throw new ArgumentNullException("window");
renderContext = new ContextHandle(Wgl.GetCurrentContext());
if (renderContext == ContextHandle.Zero)
throw new InvalidOperationException("No OpenGL context is current in the calling thread.");
currentWindow = (WinWindowInfo)window;
}
#endregion
#region --- IGraphicsContext Members ---
#region public void CreateContext()
public void CreateContext()
{
throw new NotSupportedException();
//this.CreateContext(true, null);
}
#endregion
#region public void CreateContext(bool direct)
public void CreateContext(bool direct)
{
throw new NotSupportedException();
//this.CreateContext(direct, null);
}
#endregion
#region public void CreateContext(bool direct, IGraphicsContext source)
public void CreateContext(bool direct, IGraphicsContext source)
{
throw new NotSupportedException();
}
#endregion
#region public void SwapBuffers()
public void SwapBuffers()
@ -253,13 +221,21 @@ namespace OpenTK.Platform.Windows
}
#endregion
public event DestroyEvent<IGraphicsContext> Destroy;
#endregion
#region --- IGLContextInternal Members ---
#region Implementation
IGraphicsContext IGraphicsContextInternal.Implementation
{
get { return this; }
}
#endregion
#region void LoadAll()
void IGraphicsContextInternal.LoadAll()
@ -481,12 +457,6 @@ namespace OpenTK.Platform.Windows
#endregion
#endregion
#region IGraphicsContext Members
#endregion
}
}

View file

@ -227,6 +227,17 @@ namespace OpenTK.Platform.X11
PIXMAP_BIT_SGIX = 0x00000002,
}
public enum ArbCreateContext : int
{
DebugBit = 0x0001,
ForwardCompatibleBit = 0x0002,
MajorVersion = 0x2091,
MinorVersion = 0x2092,
LayerPlane = 0x2093,
Flags = 0x2094,
ErrorInvalidVersion = 0x2095,
}
#endregion
/// <summary>
@ -322,7 +333,7 @@ namespace OpenTK.Platform.X11
unsafe public static IntPtr CreateContextAttribs(IntPtr display, IntPtr fbconfig, IntPtr share_context, bool direct, int* attribs)
{
return Delegates.glxCreateContextAttribsARB(display, fbconfig, share_context, direct, attribs);
return Delegates.glXCreateContextAttribsARB(display, fbconfig, share_context, direct, attribs);
}
public static IntPtr CreateContextAttribs(IntPtr display, IntPtr fbconfig, IntPtr share_context, bool direct, int[] attribs)
@ -331,7 +342,7 @@ namespace OpenTK.Platform.X11
{
fixed (int* attribs_ptr = attribs)
{
return Delegates.glxCreateContextAttribsARB(display, fbconfig, share_context, direct, attribs_ptr);
return Delegates.glXCreateContextAttribsARB(display, fbconfig, share_context, direct, attribs_ptr);
}
}
}
@ -339,7 +350,7 @@ namespace OpenTK.Platform.X11
#endregion
}
partial class Delegates
internal static partial class Delegates
{
[SuppressUnmanagedCodeSecurity]
public delegate int SwapIntervalSGI(int interval);
@ -347,7 +358,7 @@ namespace OpenTK.Platform.X11
[SuppressUnmanagedCodeSecurity]
unsafe public delegate IntPtr CreateContextAttribsARB(IntPtr display, IntPtr fbconfig, IntPtr share_context, bool direct, int* attribs);
unsafe public static CreateContextAttribsARB glxCreateContextAttribsARB = null;
unsafe public static CreateContextAttribsARB glXCreateContextAttribsARB = null;
}
#endregion

View file

@ -36,7 +36,7 @@ namespace OpenTK.Platform.X11
static Delegate LoadDelegate(string name, Type signature)
{
Delegate d;
string realName = name.StartsWith("glx") ? name.Substring(3) : name;
string realName = name.ToLower().StartsWith("glx") ? name.Substring(3) : name;
if (typeof(Glx).GetMethod(realName,
BindingFlags.NonPublic | BindingFlags.Static) != null)

View file

@ -25,9 +25,9 @@ namespace OpenTK.Platform.X11
return new X11XrandrDisplayDevice();
}
public IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool DirectRendering)
public IGraphicsContext CreateGLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shareContext, bool DirectRendering, int major, int minor, GraphicsContextFlags flags)
{
return new X11GLContext(mode, window, shareContext, DirectRendering);
return new X11GLContext(mode, window, shareContext, DirectRendering, major, minor, flags);
}
public IGraphicsMode CreateGraphicsMode()

View file

@ -22,11 +22,10 @@ namespace OpenTK.Platform.X11
internal sealed class X11GLContext : IGraphicsContext, IGraphicsContextInternal
{
ContextHandle context;
//X11WindowInfo window;
X11WindowInfo currentWindow;
//IntPtr visual;
bool vsync_supported;
int vsync_interval;
bool glx_loaded;
bool disposed;
@ -39,28 +38,98 @@ namespace OpenTK.Platform.X11
GraphicsContext.GetCurrentContext = X11GLContext.GetCurrentContext;
}
public X11GLContext(GraphicsMode mode, IWindowInfo info, IGraphicsContext shared, bool directRendering)
public X11GLContext(GraphicsMode mode, IWindowInfo window, IGraphicsContext shared, bool direct,
int major, int minor, GraphicsContextFlags flags)
{
//if (mode == null) mode = GraphicsMode.Default;
if (info == null) throw new ArgumentNullException("info", "Should point to a valid window.");
if (mode == null)
throw new ArgumentNullException("mode");
if (window == null)
throw new ArgumentNullException("window");
currentWindow = (X11WindowInfo)info;
currentWindow = (X11WindowInfo)window;
currentWindow.VisualInfo = SelectVisual(mode, currentWindow);
Debug.Print("Chose visual: {0}", currentWindow.VisualInfo);
ContextHandle shareHandle = shared != null ?
(shared as IGraphicsContextInternal).Context : (ContextHandle)IntPtr.Zero;
CreateContext(shared, directRendering, currentWindow);
Debug.Write("Creating X11GLContext context: ");
Debug.Write(direct ? "direct, " : "indirect, ");
Debug.WriteLine(shareHandle.Handle == IntPtr.Zero ? "not shared... " :
String.Format("shared with ({0})... ", shareHandle));
if (!glx_loaded)
{
Debug.WriteLine("Loading GLX extensions.");
// Create a temporary context to obtain the necessary function pointers.
XVisualInfo visual = currentWindow.VisualInfo;
IntPtr ctx = Glx.CreateContext(currentWindow.Display, ref visual, IntPtr.Zero, true);
if (ctx == IntPtr.Zero)
ctx = Glx.CreateContext(currentWindow.Display, ref visual, IntPtr.Zero, false);
if (ctx != IntPtr.Zero)
{
Glx.LoadAll();
Glx.MakeCurrent(currentWindow.Display, IntPtr.Zero, IntPtr.Zero);
Glx.DestroyContext(currentWindow.Display, ctx);
glx_loaded = true;
}
}
public X11GLContext(IWindowInfo window)
// Try using the new context creation method. If it fails, fall back to the old one.
// For each of these methods, we try two times to create a context:
// one with the "direct" flag intact, the other with the flag inversed.
if (Glx.Delegates.glXCreateContextAttribsARB != null)
{
if (window == null) throw new ArgumentNullException("window");
Debug.WriteLine("Using GLX_ARB_create_context...");
//renderContext = Glx.GetCurrentContext();
//if (renderContext == IntPtr.Zero)
// throw new InvalidOperationException("No OpenGL context is current in the calling thread.");
unsafe
{
// We need the FB config for the current GraphicsMode.
int count;
IntPtr* fbconfigs = Glx.ChooseFBConfig(currentWindow.Display, currentWindow.Screen,
new int[] { (int)GLXAttribute.VISUAL_ID, (int)mode.Index, 0 }, out count);
//currentWindow = window;
if (count > 0)
{
List<int> attributes = new List<int>();
attributes.Add((int)ArbCreateContext.MajorVersion);
attributes.Add(major);
attributes.Add((int)ArbCreateContext.MinorVersion);
attributes.Add(minor);
if (flags != 0)
{
attributes.Add((int)ArbCreateContext.Flags);
attributes.Add((int)flags);
}
context = new ContextHandle(Glx.Arb.CreateContextAttribs(currentWindow.Display, *fbconfigs,
shareHandle.Handle, direct, attributes.ToArray()));
if (context == ContextHandle.Zero)
context = new ContextHandle(Glx.Arb.CreateContextAttribs(currentWindow.Display, *fbconfigs,
shareHandle.Handle, !direct, attributes.ToArray()));
Functions.XFree((IntPtr)fbconfigs);
}
}
}
if (context == ContextHandle.Zero)
{
Debug.WriteLine("Using legacy context creation.");
XVisualInfo info = currentWindow.VisualInfo; // Cannot pass a Property by reference.
context = new ContextHandle(Glx.CreateContext(currentWindow.Display, ref info, shareHandle.Handle, direct));
if (context == ContextHandle.Zero)
context = new ContextHandle(Glx.CreateContext(currentWindow.Display, ref info, IntPtr.Zero, !direct));
}
if (context != ContextHandle.Zero)
Debug.Print("Success! (id: {0})", context);
else
throw new GraphicsContextException("Failed to create OpenGL context. Glx.CreateContext call returned 0.");
}
#endregion
@ -91,54 +160,6 @@ namespace OpenTK.Platform.X11
#endregion
#region void CreateContext(IGraphicsContext shareContext, bool direct)
void CreateContext(IGraphicsContext shareContext, bool direct, X11WindowInfo window)
{
try
{
ContextHandle shareHandle = shareContext != null ? (shareContext as IGraphicsContextInternal).Context :
(ContextHandle)IntPtr.Zero;
Debug.Write("Creating OpenGL context: ");
Debug.Write(direct ? "direct, " : "indirect, ");
Debug.Write(shareHandle.Handle == IntPtr.Zero ? "not shared... " :
String.Format("shared with ({0})... ", shareHandle));
lock (API.Lock)
{
XVisualInfo info = window.VisualInfo; // Cannot pass a Property by reference.
context = new ContextHandle(Glx.CreateContext(window.Display, ref info, shareHandle.Handle, direct));
// Context creation succeeded, return.
if (context != ContextHandle.Zero)
{
Debug.Print("done! (id: {0})", context);
return;
}
// Context creation failed. Retry with a non-shared context with the direct/indirect bit flipped.
Debug.Print("failed.");
Debug.Write(String.Format("Creating OpenGL context: {0}, not shared... ", !direct ? "direct" : "indirect"));
context = new ContextHandle(Glx.CreateContext(window.Display, ref info, IntPtr.Zero, !direct));
if (context != ContextHandle.Zero)
{
Debug.Print("done! (id: {0})", context);
return;
}
}
Debug.Print("failed.");
throw new GraphicsModeException("Failed to create OpenGL context. Glx.CreateContext call returned 0.");
}
finally
{
//Debug.Unindent();
}
}
#endregion
bool SupportsExtension(X11WindowInfo window, string e)
{
string extensions = Glx.QueryExtensionsString(window.Display, window.Screen);
@ -255,6 +276,15 @@ namespace OpenTK.Platform.X11
#region --- IGLContextInternal Members ---
#region Implementation
IGraphicsContext IGraphicsContextInternal.Implementation
{
get { return this; }
}
#endregion
#region void LoadAll()
void IGraphicsContextInternal.LoadAll()