[X11] Fix for issue #143

OpenTK will now use the same GLXFBConfig to create the INativeWindow
and IGraphicsContext on Linux/X11. This resolves an issue where OpenGL
3.x contexts could not be created on some graphics drivers (e.g.
nvidia binary.)
This commit is contained in:
Stefanos A. 2014-07-19 20:39:17 +02:00
parent a13a2f8e66
commit d75a2ce439
5 changed files with 199 additions and 206 deletions

View file

@ -248,11 +248,7 @@ namespace OpenTK.Platform
window.Screen = screen; window.Screen = screen;
window.Handle = windowHandle; window.Handle = windowHandle;
window.RootWindow = rootWindow; window.RootWindow = rootWindow;
if (visualInfo != IntPtr.Zero) window.Visual = visualInfo;
{
window.VisualInfo = (X11.XVisualInfo)Marshal.PtrToStructure(visualInfo, typeof(X11.XVisualInfo));
}
return window; return window;
} }

View file

@ -78,12 +78,25 @@ namespace OpenTK.Platform.X11
} }
} }
Mode = ModeSelector.SelectGraphicsMode( IntPtr visual = IntPtr.Zero;
mode.ColorFormat, mode.Depth, mode.Stencil, mode.Samples, IntPtr fbconfig = IntPtr.Zero;
mode.AccumulatorFormat, mode.Buffers, mode.Stereo);
// Once a window has a visual, we cannot use a different
// visual on the OpenGL context, or glXMakeCurrent might fail.
// Note: we should only check X11WindowInfo.Visual, as that
// is the only property that can be set by Utilities.CreateX11WindowInfo.
currentWindow = (X11WindowInfo)window; currentWindow = (X11WindowInfo)window;
currentWindow.VisualInfo = SelectVisual(Mode, currentWindow); if (currentWindow.Visual != IntPtr.Zero)
{
visual = currentWindow.Visual;
fbconfig = currentWindow.FBConfig;
Mode = currentWindow.GraphicsMode;
}
if (!Mode.Index.HasValue)
{
Mode = ModeSelector.SelectGraphicsMode(mode, out visual, out fbconfig);
}
ContextHandle shareHandle = shared != null ? ContextHandle shareHandle = shared != null ?
(shared as IGraphicsContextInternal).Context : (ContextHandle)IntPtr.Zero; (shared as IGraphicsContextInternal).Context : (ContextHandle)IntPtr.Zero;
@ -99,84 +112,15 @@ namespace OpenTK.Platform.X11
// HACK: It seems that Catalyst 9.1 - 9.4 on Linux have problems with contexts created through // HACK: It seems that Catalyst 9.1 - 9.4 on Linux have problems with contexts created through
// GLX_ARB_create_context, including hideous input lag, no vsync and other madness. // GLX_ARB_create_context, including hideous input lag, no vsync and other madness.
// Use legacy context creation if the user doesn't request a 3.0+ context. // Use legacy context creation if the user doesn't request a 3.0+ context.
if ((major * 10 + minor >= 30) && SupportsCreateContextAttribs(Display, currentWindow)) if (fbconfig != IntPtr.Zero && (major * 10 + minor >= 30) && SupportsCreateContextAttribs(Display, currentWindow))
{ {
Debug.Write("Using GLX_ARB_create_context... "); Handle = CreateContextAttribs(Display, currentWindow.Screen,
fbconfig, direct, major, minor, flags, shareHandle);
unsafe
{
// We need the FB config for the current GraphicsMode.
int count;
IntPtr* fbconfigs = Glx.ChooseFBConfig(Display, currentWindow.Screen,
new int[] {
(int)GLXAttribute.VISUAL_ID,
(int)Mode.Index,
0
}, out count);
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)GetARBContextFlags(flags));
attributes.Add((int)ArbCreateContext.ProfileMask);
attributes.Add((int)GetARBProfileFlags(flags));
}
// According to the docs, " <attribList> specifies a list of attributes for the context.
// The list consists of a sequence of <name,value> pairs terminated by the
// value 0. [...]"
// Is this a single 0, or a <0, 0> pair? (Defensive coding: add two zeroes just in case).
attributes.Add(0);
attributes.Add(0);
using (new XLock(Display))
{
Handle = new ContextHandle(Glx.Arb.CreateContextAttribs(Display, *fbconfigs,
shareHandle.Handle, direct, attributes.ToArray()));
if (Handle == ContextHandle.Zero)
{
Debug.Write(String.Format("failed. Trying direct: {0}... ", !direct));
Handle = new ContextHandle(Glx.Arb.CreateContextAttribs(Display, *fbconfigs,
shareHandle.Handle, !direct, attributes.ToArray()));
}
}
if (Handle == ContextHandle.Zero)
Debug.WriteLine("failed.");
else
Debug.WriteLine("success!");
using (new XLock(Display))
{
Functions.XFree((IntPtr)fbconfigs);
}
}
}
} }
if (Handle == ContextHandle.Zero) if (Handle == ContextHandle.Zero)
{ {
Debug.Write("Using legacy context creation... "); Handle = CreateContextLegacy(Display, currentWindow.VisualInfo, direct, shareHandle);
XVisualInfo info = currentWindow.VisualInfo;
using (new XLock(Display))
{
// Cannot pass a Property by reference.
Handle = new ContextHandle(Glx.CreateContext(Display, ref info, shareHandle.Handle, direct));
if (Handle == ContextHandle.Zero)
{
Debug.WriteLine(String.Format("failed. Trying direct: {0}... ", !direct));
Handle = new ContextHandle(Glx.CreateContext(Display, ref info, IntPtr.Zero, !direct));
}
}
} }
if (Handle != ContextHandle.Zero) if (Handle != ContextHandle.Zero)
@ -208,6 +152,74 @@ namespace OpenTK.Platform.X11
#region --- Private Methods --- #region --- Private Methods ---
static ContextHandle CreateContextAttribs(
IntPtr display, int screen, IntPtr fbconfig,
bool direct, int major, int minor,
GraphicsContextFlags flags, ContextHandle shareContext)
{
Debug.Write("Using GLX_ARB_create_context... ");
IntPtr context = IntPtr.Zero;
{
// We need the FB config for the current GraphicsMode.
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)GetARBContextFlags(flags));
attributes.Add((int)ArbCreateContext.ProfileMask);
attributes.Add((int)GetARBProfileFlags(flags));
}
// According to the docs, " <attribList> specifies a list of attributes for the context.
// The list consists of a sequence of <name,value> pairs terminated by the
// value 0. [...]"
// Is this a single 0, or a <0, 0> pair? (Defensive coding: add two zeroes just in case).
attributes.Add(0);
attributes.Add(0);
using (new XLock(display))
{
context = Glx.Arb.CreateContextAttribs(display, fbconfig, shareContext.Handle, direct, attributes.ToArray());
if (context == IntPtr.Zero)
{
Debug.Write(String.Format("failed. Trying direct: {0}... ", !direct));
context = Glx.Arb.CreateContextAttribs(display, fbconfig, shareContext.Handle, !direct, attributes.ToArray());
}
}
if (context == IntPtr.Zero)
Debug.WriteLine("failed.");
else
Debug.WriteLine("success!");
}
return new ContextHandle(context);
}
static ContextHandle CreateContextLegacy(IntPtr display,
XVisualInfo info, bool direct, ContextHandle shareContext)
{
Debug.Write("Using legacy context creation... ");
IntPtr context;
using (new XLock(display))
{
// Cannot pass a Property by reference.
context = Glx.CreateContext(display, ref info, shareContext.Handle, direct);
if (context == IntPtr.Zero)
{
Debug.WriteLine(String.Format("failed. Trying direct: {0}... ", !direct));
context = Glx.CreateContext(display, ref info, IntPtr.Zero, !direct);
}
}
return new ContextHandle(context);
}
IntPtr Display IntPtr Display
{ {
get { return display; } get { return display; }
@ -221,38 +233,14 @@ namespace OpenTK.Platform.X11
} }
} }
#region XVisualInfo SelectVisual(GraphicsMode mode, X11WindowInfo currentWindow) static ArbCreateContext GetARBContextFlags(GraphicsContextFlags flags)
XVisualInfo SelectVisual(GraphicsMode mode, X11WindowInfo currentWindow)
{
XVisualInfo info = new XVisualInfo();
info.VisualID = (IntPtr)mode.Index;
info.Screen = currentWindow.Screen;
int items;
lock (API.Lock)
{
IntPtr vs = Functions.XGetVisualInfo(Display, XVisualInfoMask.ID | XVisualInfoMask.Screen, ref info, out items);
if (items == 0)
throw new GraphicsModeException(String.Format("Invalid GraphicsMode specified ({0}).", mode));
info = (XVisualInfo)Marshal.PtrToStructure(vs, typeof(XVisualInfo));
Functions.XFree(vs);
}
return info;
}
#endregion
ArbCreateContext GetARBContextFlags(GraphicsContextFlags flags)
{ {
ArbCreateContext result = 0; ArbCreateContext result = 0;
result |= (flags & GraphicsContextFlags.Debug) != 0 ? ArbCreateContext.DebugBit : 0; result |= (flags & GraphicsContextFlags.Debug) != 0 ? ArbCreateContext.DebugBit : 0;
return result; return result;
} }
ArbCreateContext GetARBProfileFlags(GraphicsContextFlags flags) static ArbCreateContext GetARBProfileFlags(GraphicsContextFlags flags)
{ {
ArbCreateContext result = 0; ArbCreateContext result = 0;
result |= (flags & GraphicsContextFlags.ForwardCompatible) != 0 ? result |= (flags & GraphicsContextFlags.ForwardCompatible) != 0 ?

View file

@ -154,17 +154,13 @@ namespace OpenTK.Platform.X11
using (new XLock(window.Display)) using (new XLock(window.Display))
{ {
if (!mode.Index.HasValue) IntPtr visual;
{ IntPtr fbconfig;
mode = new X11GraphicsMode().SelectGraphicsMode( window.GraphicsMode = new X11GraphicsMode()
mode.ColorFormat, mode.Depth, mode.Stencil, mode.Samples, .SelectGraphicsMode(mode, out visual, out fbconfig);
mode.AccumulatorFormat, mode.Buffers, mode.Stereo);
}
info.VisualID = mode.Index.Value; window.Visual = visual;
int dummy; window.FBConfig = fbconfig;
window.VisualInfo = (XVisualInfo)Marshal.PtrToStructure(
Functions.XGetVisualInfo(window.Display, XVisualInfoMask.ID, ref info, out dummy), typeof(XVisualInfo));
// Create a window on this display using the visual above // Create a window on this display using the visual above
Debug.Write("Opening render window... "); Debug.Write("Opening render window... ");

View file

@ -16,7 +16,7 @@ using OpenTK.Graphics;
namespace OpenTK.Platform.X11 namespace OpenTK.Platform.X11
{ {
class X11GraphicsMode : IGraphicsMode class X11GraphicsMode
{ {
// Todo: Add custom visual selection algorithm, instead of ChooseFBConfig/ChooseVisual. // Todo: Add custom visual selection algorithm, instead of ChooseFBConfig/ChooseVisual.
// It seems the Choose* methods do not take multisampling into account (at least on some // It seems the Choose* methods do not take multisampling into account (at least on some
@ -32,34 +32,45 @@ namespace OpenTK.Platform.X11
#region IGraphicsMode Members #region IGraphicsMode Members
public GraphicsMode SelectGraphicsMode(ColorFormat color, int depth, int stencil, int samples, ColorFormat accum, public GraphicsMode SelectGraphicsMode(GraphicsMode desired_mode, out IntPtr visual, out IntPtr fbconfig)
int buffers, bool stereo)
{ {
GraphicsMode gfx; GraphicsMode gfx;
// The actual GraphicsMode that will be selected. GraphicsMode mode = new GraphicsMode(desired_mode);
IntPtr visual = IntPtr.Zero; visual = IntPtr.Zero;
fbconfig = IntPtr.Zero;
IntPtr display = API.DefaultDisplay; IntPtr display = API.DefaultDisplay;
do do
{ {
// Try to select a visual using Glx.ChooseFBConfig and Glx.GetVisualFromFBConfig. // Try to select a visual using Glx.ChooseFBConfig and Glx.GetVisualFromFBConfig.
// This is only supported on GLX 1.3 - if it fails, fall back to Glx.ChooseVisual. // This is only supported on GLX 1.3 - if it fails, fall back to Glx.ChooseVisual.
visual = SelectVisualUsingFBConfig(color, depth, stencil, samples, accum, buffers, stereo); fbconfig = SelectFBConfig(mode);
if (fbconfig != IntPtr.Zero)
visual = Glx.GetVisualFromFBConfig(display, fbconfig);
if (visual == IntPtr.Zero) if (visual == IntPtr.Zero)
visual = SelectVisualUsingChooseVisual(color, depth, stencil, samples, accum, buffers, stereo); visual = SelectVisual(mode);
if (visual == IntPtr.Zero) if (visual == IntPtr.Zero)
{ {
// Relax parameters and retry // Relax parameters and retry
if (!Utilities.RelaxGraphicsMode(ref color, ref depth, ref stencil, ref samples, ref accum, ref buffers, ref stereo)) if (!Utilities.RelaxGraphicsMode(ref mode))
throw new GraphicsModeException("Requested GraphicsMode not available."); throw new GraphicsModeException("Requested GraphicsMode not available.");
} }
} }
while (visual == IntPtr.Zero); while (visual == IntPtr.Zero);
XVisualInfo info = (XVisualInfo)Marshal.PtrToStructure(visual, typeof(XVisualInfo)); XVisualInfo info = (XVisualInfo)Marshal.PtrToStructure(visual, typeof(XVisualInfo));
gfx = CreateGraphicsMode(display, ref info);
return gfx;
}
#endregion
#region Private Members
static GraphicsMode CreateGraphicsMode(IntPtr display, ref XVisualInfo info)
{
// See what we *really* got: // See what we *really* got:
int r, g, b, a; int r, g, b, a;
Glx.GetConfig(display, ref info, GLXAttribute.ALPHA_SIZE, out a); Glx.GetConfig(display, ref info, GLXAttribute.ALPHA_SIZE, out a);
@ -71,99 +82,84 @@ namespace OpenTK.Platform.X11
Glx.GetConfig(display, ref info, GLXAttribute.ACCUM_RED_SIZE, out ar); Glx.GetConfig(display, ref info, GLXAttribute.ACCUM_RED_SIZE, out ar);
Glx.GetConfig(display, ref info, GLXAttribute.ACCUM_GREEN_SIZE, out ag); Glx.GetConfig(display, ref info, GLXAttribute.ACCUM_GREEN_SIZE, out ag);
Glx.GetConfig(display, ref info, GLXAttribute.ACCUM_BLUE_SIZE, out ab); Glx.GetConfig(display, ref info, GLXAttribute.ACCUM_BLUE_SIZE, out ab);
int depth, stencil, samples, buffers;
Glx.GetConfig(display, ref info, GLXAttribute.DEPTH_SIZE, out depth); Glx.GetConfig(display, ref info, GLXAttribute.DEPTH_SIZE, out depth);
Glx.GetConfig(display, ref info, GLXAttribute.STENCIL_SIZE, out stencil); Glx.GetConfig(display, ref info, GLXAttribute.STENCIL_SIZE, out stencil);
Glx.GetConfig(display, ref info, GLXAttribute.SAMPLES, out samples); Glx.GetConfig(display, ref info, GLXAttribute.SAMPLES, out samples);
Glx.GetConfig(display, ref info, GLXAttribute.DOUBLEBUFFER, out buffers); Glx.GetConfig(display, ref info, GLXAttribute.DOUBLEBUFFER, out buffers);
++buffers;
// the above lines returns 0 - false and 1 - true.
int st; int st;
Glx.GetConfig(display, ref info, GLXAttribute.STEREO, out st); Glx.GetConfig(display, ref info, GLXAttribute.STEREO, out st);
stereo = st != 0;
gfx = new GraphicsMode(info.VisualID, new ColorFormat(r, g, b, a), depth, stencil, samples, // Note: Glx.GetConfig return buffers = 0 (false) or 1 (true).
new ColorFormat(ar, ag, ab, aa), buffers, stereo); // OpenTK expects buffers = 1 (single-) or 2 (double-buffering),
// so increase the GLX value by one.
using (new XLock(display)) return new GraphicsMode(info.VisualID, new ColorFormat(r, g, b, a), depth, stencil, samples,
{ new ColorFormat(ar, ag, ab, aa), buffers + 1, st != 0);
Functions.XFree(visual);
} }
return gfx; IntPtr SelectFBConfig(GraphicsMode mode)
}
#endregion
#region Private Members
// See http://publib.boulder.ibm.com/infocenter/systems/index.jsp?topic=/com.ibm.aix.opengl/doc/openglrf/glXChooseFBConfig.htm
// for the attribute declarations. Note that the attributes are different than those used in Glx.ChooseVisual.
IntPtr SelectVisualUsingFBConfig(ColorFormat color, int depth, int stencil, int samples, ColorFormat accum,
int buffers, bool stereo)
{ {
Debug.Print("Selecting FB config for {0}", mode);
List<int> visualAttributes = new List<int>(); List<int> visualAttributes = new List<int>();
IntPtr visual = IntPtr.Zero; IntPtr visual = IntPtr.Zero;
Debug.Print("Bits per pixel: {0}", color.BitsPerPixel); if (mode.ColorFormat.BitsPerPixel > 0)
if (color.BitsPerPixel > 0)
{ {
if (!color.IsIndexed) if (!mode.ColorFormat.IsIndexed)
{ {
visualAttributes.Add((int)GLXAttribute.RGBA); visualAttributes.Add((int)GLXAttribute.RENDER_TYPE);
visualAttributes.Add(1); visualAttributes.Add((int)GLXRenderTypeMask.RGBA_BIT);
} }
visualAttributes.Add((int)GLXAttribute.RED_SIZE); visualAttributes.Add((int)GLXAttribute.RED_SIZE);
visualAttributes.Add(color.Red); visualAttributes.Add(mode.ColorFormat.Red);
visualAttributes.Add((int)GLXAttribute.GREEN_SIZE); visualAttributes.Add((int)GLXAttribute.GREEN_SIZE);
visualAttributes.Add(color.Green); visualAttributes.Add(mode.ColorFormat.Green);
visualAttributes.Add((int)GLXAttribute.BLUE_SIZE); visualAttributes.Add((int)GLXAttribute.BLUE_SIZE);
visualAttributes.Add(color.Blue); visualAttributes.Add(mode.ColorFormat.Blue);
visualAttributes.Add((int)GLXAttribute.ALPHA_SIZE); visualAttributes.Add((int)GLXAttribute.ALPHA_SIZE);
visualAttributes.Add(color.Alpha); visualAttributes.Add(mode.ColorFormat.Alpha);
} }
Debug.Print("Depth: {0}", depth); if (mode.Depth > 0)
if (depth > 0)
{ {
visualAttributes.Add((int)GLXAttribute.DEPTH_SIZE); visualAttributes.Add((int)GLXAttribute.DEPTH_SIZE);
visualAttributes.Add(depth); visualAttributes.Add(mode.Depth);
} }
if (buffers > 1) if (mode.Buffers > 1)
{ {
visualAttributes.Add((int)GLXAttribute.DOUBLEBUFFER); visualAttributes.Add((int)GLXAttribute.DOUBLEBUFFER);
visualAttributes.Add(1); visualAttributes.Add(1);
} }
if (stencil > 1) if (mode.Stereo)
{ {
visualAttributes.Add((int)GLXAttribute.STENCIL_SIZE); visualAttributes.Add((int)GLXAttribute.STENCIL_SIZE);
visualAttributes.Add(stencil); visualAttributes.Add(mode.Stereo ? 1 : 0);
} }
if (accum.BitsPerPixel > 0) if (mode.AccumulatorFormat.BitsPerPixel > 0)
{ {
visualAttributes.Add((int)GLXAttribute.ACCUM_ALPHA_SIZE); visualAttributes.Add((int)GLXAttribute.ACCUM_ALPHA_SIZE);
visualAttributes.Add(accum.Alpha); visualAttributes.Add(mode.AccumulatorFormat.Alpha);
visualAttributes.Add((int)GLXAttribute.ACCUM_BLUE_SIZE); visualAttributes.Add((int)GLXAttribute.ACCUM_BLUE_SIZE);
visualAttributes.Add(accum.Blue); visualAttributes.Add(mode.AccumulatorFormat.Blue);
visualAttributes.Add((int)GLXAttribute.ACCUM_GREEN_SIZE); visualAttributes.Add((int)GLXAttribute.ACCUM_GREEN_SIZE);
visualAttributes.Add(accum.Green); visualAttributes.Add(mode.AccumulatorFormat.Green);
visualAttributes.Add((int)GLXAttribute.ACCUM_RED_SIZE); visualAttributes.Add((int)GLXAttribute.ACCUM_RED_SIZE);
visualAttributes.Add(accum.Red); visualAttributes.Add(mode.AccumulatorFormat.Red);
} }
if (samples > 0) if (mode.Samples > 0)
{ {
visualAttributes.Add((int)GLXAttribute.SAMPLE_BUFFERS); visualAttributes.Add((int)GLXAttribute.SAMPLE_BUFFERS);
visualAttributes.Add(1); visualAttributes.Add(1);
visualAttributes.Add((int)GLXAttribute.SAMPLES); visualAttributes.Add((int)GLXAttribute.SAMPLES);
visualAttributes.Add(samples); visualAttributes.Add(mode.Samples);
} }
if (stereo) if (mode.Stereo)
{ {
visualAttributes.Add((int)GLXAttribute.STEREO); visualAttributes.Add((int)GLXAttribute.STEREO);
visualAttributes.Add(1); visualAttributes.Add(1);
@ -173,6 +169,7 @@ namespace OpenTK.Platform.X11
// Select a visual that matches the parameters set by the user. // Select a visual that matches the parameters set by the user.
IntPtr display = API.DefaultDisplay; IntPtr display = API.DefaultDisplay;
IntPtr result = IntPtr.Zero;
using (new XLock(display)) using (new XLock(display))
{ {
try try
@ -190,81 +187,82 @@ namespace OpenTK.Platform.X11
if (fbcount > 0 && fbconfigs != null) if (fbcount > 0 && fbconfigs != null)
{ {
// We want to use the first GLXFBConfig from the fbconfigs array (the first one is the best match). // We want to use the first GLXFBConfig from the fbconfigs array (the first one is the best match).
visual = Glx.GetVisualFromFBConfig(display, *fbconfigs); Debug.Print("Selected FB config: {0}", *fbconfigs);
result = *fbconfigs;
Functions.XFree((IntPtr)fbconfigs); Functions.XFree((IntPtr)fbconfigs);
} }
else
{
Debug.Print("No matching FB config found.");
}
} }
} }
catch (EntryPointNotFoundException) catch (EntryPointNotFoundException)
{ {
Debug.Print("Function glXChooseFBConfig not supported."); Debug.Print("Function glXChooseFBConfig not supported.");
return IntPtr.Zero;
} }
} }
return visual; return result;
} }
// See http://publib.boulder.ibm.com/infocenter/systems/index.jsp?topic=/com.ibm.aix.opengl/doc/openglrf/glXChooseVisual.htm IntPtr SelectVisual(GraphicsMode mode)
IntPtr SelectVisualUsingChooseVisual(ColorFormat color, int depth, int stencil, int samples, ColorFormat accum,
int buffers, bool stereo)
{ {
Debug.Print("Selecting FB config for {0}", mode);
List<int> visualAttributes = new List<int>(); List<int> visualAttributes = new List<int>();
Debug.Print("Bits per pixel: {0}", color.BitsPerPixel); if (mode.ColorFormat.BitsPerPixel > 0)
if (color.BitsPerPixel > 0)
{ {
if (!color.IsIndexed) if (!mode.ColorFormat.IsIndexed)
visualAttributes.Add((int)GLXAttribute.RGBA); visualAttributes.Add((int)GLXAttribute.RGBA);
visualAttributes.Add((int)GLXAttribute.RED_SIZE); visualAttributes.Add((int)GLXAttribute.RED_SIZE);
visualAttributes.Add(color.Red); visualAttributes.Add(mode.ColorFormat.Red);
visualAttributes.Add((int)GLXAttribute.GREEN_SIZE); visualAttributes.Add((int)GLXAttribute.GREEN_SIZE);
visualAttributes.Add(color.Green); visualAttributes.Add(mode.ColorFormat.Green);
visualAttributes.Add((int)GLXAttribute.BLUE_SIZE); visualAttributes.Add((int)GLXAttribute.BLUE_SIZE);
visualAttributes.Add(color.Blue); visualAttributes.Add(mode.ColorFormat.Blue);
visualAttributes.Add((int)GLXAttribute.ALPHA_SIZE); visualAttributes.Add((int)GLXAttribute.ALPHA_SIZE);
visualAttributes.Add(color.Alpha); visualAttributes.Add(mode.ColorFormat.Alpha);
} }
Debug.Print("Depth: {0}", depth);
if (depth > 0) if (mode.Depth > 0)
{ {
visualAttributes.Add((int)GLXAttribute.DEPTH_SIZE); visualAttributes.Add((int)GLXAttribute.DEPTH_SIZE);
visualAttributes.Add(depth); visualAttributes.Add(mode.Depth);
} }
if (buffers > 1) if (mode.Buffers > 1)
visualAttributes.Add((int)GLXAttribute.DOUBLEBUFFER); visualAttributes.Add((int)GLXAttribute.DOUBLEBUFFER);
if (stencil > 1) if (mode.Stencil > 1)
{ {
visualAttributes.Add((int)GLXAttribute.STENCIL_SIZE); visualAttributes.Add((int)GLXAttribute.STENCIL_SIZE);
visualAttributes.Add(stencil); visualAttributes.Add(mode.Stencil);
} }
if (accum.BitsPerPixel > 0) if (mode.AccumulatorFormat.BitsPerPixel > 0)
{ {
visualAttributes.Add((int)GLXAttribute.ACCUM_ALPHA_SIZE); visualAttributes.Add((int)GLXAttribute.ACCUM_ALPHA_SIZE);
visualAttributes.Add(accum.Alpha); visualAttributes.Add(mode.AccumulatorFormat.Alpha);
visualAttributes.Add((int)GLXAttribute.ACCUM_BLUE_SIZE); visualAttributes.Add((int)GLXAttribute.ACCUM_BLUE_SIZE);
visualAttributes.Add(accum.Blue); visualAttributes.Add(mode.AccumulatorFormat.Blue);
visualAttributes.Add((int)GLXAttribute.ACCUM_GREEN_SIZE); visualAttributes.Add((int)GLXAttribute.ACCUM_GREEN_SIZE);
visualAttributes.Add(accum.Green); visualAttributes.Add(mode.AccumulatorFormat.Green);
visualAttributes.Add((int)GLXAttribute.ACCUM_RED_SIZE); visualAttributes.Add((int)GLXAttribute.ACCUM_RED_SIZE);
visualAttributes.Add(accum.Red); visualAttributes.Add(mode.AccumulatorFormat.Red);
} }
if (samples > 0) if (mode.Samples > 0)
{ {
visualAttributes.Add((int)GLXAttribute.SAMPLE_BUFFERS); visualAttributes.Add((int)GLXAttribute.SAMPLE_BUFFERS);
visualAttributes.Add(1); visualAttributes.Add(1);
visualAttributes.Add((int)GLXAttribute.SAMPLES); visualAttributes.Add((int)GLXAttribute.SAMPLES);
visualAttributes.Add(samples); visualAttributes.Add(mode.Samples);
} }
if (stereo) if (mode.Stereo)
visualAttributes.Add((int)GLXAttribute.STEREO); visualAttributes.Add((int)GLXAttribute.STEREO);
visualAttributes.Add(0); visualAttributes.Add(0);

View file

@ -27,6 +27,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text; using System.Text;
namespace OpenTK.Platform.X11 namespace OpenTK.Platform.X11
@ -87,7 +88,17 @@ namespace OpenTK.Platform.X11
/// <summary>Gets or sets the X11 screen.</summary> /// <summary>Gets or sets the X11 screen.</summary>
public int Screen { get { return screen; } set { screen = value; } } public int Screen { get { return screen; } set { screen = value; } }
/// <summary>Gets or sets the X11 VisualInfo.</summary> /// <summary>Gets or sets the X11 VisualInfo.</summary>
public XVisualInfo VisualInfo { get { return visualInfo; } set { visualInfo = value; } } public XVisualInfo VisualInfo
{
get
{
if (Visual != IntPtr.Zero)
{
return (XVisualInfo)Marshal.PtrToStructure(Visual, typeof(XVisualInfo));
}
return default(XVisualInfo);
}
}
/// <summary>Gets or sets the X11 EventMask.</summary> /// <summary>Gets or sets the X11 EventMask.</summary>
public EventMask EventMask { get { return eventMask; } set { eventMask = value; } } public EventMask EventMask { get { return eventMask; } set { eventMask = value; } }
@ -96,6 +107,10 @@ namespace OpenTK.Platform.X11
// (e.g. MonoGame) // (e.g. MonoGame)
public IntPtr WindowHandle { get { return Handle; } set { Handle = value; } } public IntPtr WindowHandle { get { return Handle; } set { Handle = value; } }
public IntPtr Visual { get; set; }
public IntPtr FBConfig { get; set; }
public Graphics.GraphicsMode GraphicsMode { get; set; }
#endregion #endregion
#region --- IDisposable Members --- #region --- IDisposable Members ---