IntPtr SelectVisualUsingFBConfig(ColorFormat color, int depth, int stencil, int samples, ColorFormat accum,
int buffers, bool stereo)
{
List<int> visualAttributes = new List<int>();
IntPtr visual = IntPtr.Zero;
Debug.Print("Bits per pixel: {0}", color.BitsPerPixel);
if (color.BitsPerPixel > 0)
{
if (!color.IsIndexed)
{
visualAttributes.Add((int)GLXAttribute.RGBA);
visualAttributes.Add(1);
}
visualAttributes.Add((int)GLXAttribute.RED_SIZE);
visualAttributes.Add(color.Red);
visualAttributes.Add((int)GLXAttribute.GREEN_SIZE);
visualAttributes.Add(color.Green);
visualAttributes.Add((int)GLXAttribute.BLUE_SIZE);
visualAttributes.Add(color.Blue);
visualAttributes.Add((int)GLXAttribute.ALPHA_SIZE);
visualAttributes.Add(color.Alpha);
}
Debug.Print("Depth: {0}", depth);
if (depth > 0)
{
visualAttributes.Add((int)GLXAttribute.DEPTH_SIZE);
visualAttributes.Add(depth);
}
if (buffers > 1)
{
visualAttributes.Add((int)GLXAttribute.DOUBLEBUFFER);
visualAttributes.Add(1);
}
if (stencil > 1)
{
visualAttributes.Add((int)GLXAttribute.STENCIL_SIZE);
visualAttributes.Add(stencil);
}
if (accum.BitsPerPixel > 0)
{
visualAttributes.Add((int)GLXAttribute.ACCUM_ALPHA_SIZE);
visualAttributes.Add(accum.Alpha);
visualAttributes.Add((int)GLXAttribute.ACCUM_BLUE_SIZE);
visualAttributes.Add(accum.Blue);
visualAttributes.Add((int)GLXAttribute.ACCUM_GREEN_SIZE);
visualAttributes.Add(accum.Green);
visualAttributes.Add((int)GLXAttribute.ACCUM_RED_SIZE);
visualAttributes.Add(accum.Red);
}
if (samples > 0)
{
visualAttributes.Add((int)GLXAttribute.SAMPLE_BUFFERS);
visualAttributes.Add(1);
visualAttributes.Add((int)GLXAttribute.SAMPLES);
visualAttributes.Add(samples);
}
if (stereo)
{
visualAttributes.Add((int)GLXAttribute.STEREO);
visualAttributes.Add(1);
}
visualAttributes.Add(0);
// Select a visual that matches the parameters set by the user.
IntPtr display = API.DefaultDisplay;
using (new XLock(display))
{
try
{
int screen = Functions.XDefaultScreen(display);
IntPtr root = Functions.XRootWindow(display, screen);
Debug.Print("Display: {0}, Screen: {1}, RootWindow: {2}", display, screen, root);
unsafe
{
Debug.Print("Getting FB config.");
int fbcount;
// Note that ChooseFBConfig returns an array of GLXFBConfig opaque structures (i.e. mapped to IntPtrs).
IntPtr* fbconfigs = Glx.ChooseFBConfig(display, screen, visualAttributes.ToArray(), out fbcount);
if (fbcount > 0 && fbconfigs != null)
{
// We want to use the first GLXFBConfig from the fbconfigs array (the first one is the best match).
visual = Glx.GetVisualFromFBConfig(display, *fbconfigs);
Functions.XFree((IntPtr)fbconfigs);
}
}
}
catch (EntryPointNotFoundException)
{
Debug.Print("Function glXChooseFBConfig not supported.");
return IntPtr.Zero;
}
}
return visual;
}