Prioritize accelerated formats first
Instead of creating a list of all available formats and iterating through that, we let the driver decide which is the best accelerated format to use for the user parameters. If no such format exists, we fall back to generic acceleration or software acceleration, in turn. This affects issue #21
This commit is contained in:
parent
030cf937a0
commit
0ad87bec3d
1 changed files with 250 additions and 160 deletions
|
@ -37,27 +37,28 @@ namespace OpenTK.Platform.Windows
|
||||||
{
|
{
|
||||||
class WinGraphicsMode : IGraphicsMode
|
class WinGraphicsMode : IGraphicsMode
|
||||||
{
|
{
|
||||||
#region Fields
|
enum AccelerationType
|
||||||
|
{
|
||||||
|
// Software acceleration
|
||||||
|
None = 0,
|
||||||
|
// Partial acceleration (Direct3D emulation)
|
||||||
|
MCD,
|
||||||
|
// Full acceleration
|
||||||
|
ICD,
|
||||||
|
}
|
||||||
|
|
||||||
readonly List<GraphicsMode> modes = new List<GraphicsMode>();
|
|
||||||
static readonly object SyncRoot = new object();
|
static readonly object SyncRoot = new object();
|
||||||
|
readonly IntPtr Device;
|
||||||
#endregion
|
readonly List<GraphicsMode> modes = new List<GraphicsMode>();
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
|
|
||||||
public WinGraphicsMode(IntPtr device)
|
public WinGraphicsMode(IntPtr device)
|
||||||
{
|
{
|
||||||
lock (SyncRoot)
|
if (device == IntPtr.Zero)
|
||||||
{
|
throw new ArgumentException();
|
||||||
modes.AddRange(GetModesARB(device));
|
|
||||||
if (modes.Count == 0)
|
Device = device;
|
||||||
modes.AddRange(GetModesPFD(device));
|
|
||||||
if (modes.Count == 0)
|
|
||||||
throw new GraphicsModeException(
|
|
||||||
"No GraphicsMode available. This should never happen, please report a bug at http://www.opentk.com");
|
|
||||||
modes.Sort(new GraphicsModeComparer());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -67,57 +68,172 @@ namespace OpenTK.Platform.Windows
|
||||||
public GraphicsMode SelectGraphicsMode(ColorFormat color, int depth, int stencil, int samples,
|
public GraphicsMode SelectGraphicsMode(ColorFormat color, int depth, int stencil, int samples,
|
||||||
ColorFormat accum, int buffers, bool stereo)
|
ColorFormat accum, int buffers, bool stereo)
|
||||||
{
|
{
|
||||||
GraphicsMode mode = null;
|
GraphicsMode mode = new GraphicsMode(color, depth, stencil, samples,accum, buffers, stereo);
|
||||||
do
|
GraphicsMode created_mode = ChoosePixelFormatARB(Device, mode);
|
||||||
|
|
||||||
|
// If ChoosePixelFormatARB failed, iterate through all acceleration types in turn (ICD, MCD, None)
|
||||||
|
// This should fix issue #2224, which causes OpenTK to fail on VMs without hardware acceleration.
|
||||||
|
created_mode = created_mode ?? ChoosePixelFormatPFD(Device, mode, AccelerationType.ICD);
|
||||||
|
created_mode = created_mode ?? ChoosePixelFormatPFD(Device, mode, AccelerationType.MCD);
|
||||||
|
created_mode = created_mode ?? ChoosePixelFormatPFD(Device, mode, AccelerationType.None);
|
||||||
|
|
||||||
|
if (created_mode == null)
|
||||||
{
|
{
|
||||||
mode = modes.Find(delegate(GraphicsMode current)
|
throw new GraphicsModeException("The requested GraphicsMode is not supported");
|
||||||
{
|
}
|
||||||
return ModeSelector(current, color, depth, stencil, samples, accum, buffers, stereo);
|
|
||||||
});
|
|
||||||
} while (mode == null && RelaxParameters(
|
|
||||||
ref color, ref depth, ref stencil, ref samples, ref accum, ref buffers, ref stereo));
|
|
||||||
|
|
||||||
if (mode == null)
|
return created_mode;
|
||||||
mode = modes[0];
|
|
||||||
|
|
||||||
return mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RelaxParameters(ref ColorFormat color, ref int depth, ref int stencil, ref int samples,
|
|
||||||
ref ColorFormat accum, ref int buffers, ref bool stereo)
|
|
||||||
{
|
|
||||||
if (stereo) { stereo = false; return true; }
|
|
||||||
if (buffers != 2) { buffers = 2; return true; }
|
|
||||||
if (accum != 0) { accum = 0; return true; }
|
|
||||||
if (samples != 0) { samples = 0; return true; }
|
|
||||||
if (depth < 16) { depth = 16; return true; }
|
|
||||||
if (depth != 24) { depth = 24; return true; }
|
|
||||||
if (stencil > 0 && stencil != 8) { stencil = 8; return true; }
|
|
||||||
if (stencil == 8) { stencil = 0; return true; }
|
|
||||||
if (color < 8) { color = 8; return true; }
|
|
||||||
if (color < 16) { color = 16; return true; }
|
|
||||||
if (color < 24) { color = 24; return true; }
|
|
||||||
if (color < 32 || color > 32) { color = 32; return true; }
|
|
||||||
return false; // We tried everything we could, no match found.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Private Methods
|
#region Private Methods
|
||||||
|
|
||||||
#region GetModesPFD
|
#region ChoosePixelFormatARB
|
||||||
|
|
||||||
IEnumerable<GraphicsMode> GetModesPFD(IntPtr device)
|
// Queries pixel formats through the WGL_ARB_pixel_format extension
|
||||||
|
// This method only returns accelerated formats. If no format offers
|
||||||
|
// hardware acceleration (e.g. we are running in a VM or in a remote desktop
|
||||||
|
// connection), this method will return 0 formats and we will fall back to
|
||||||
|
// ChoosePixelFormatPFD.
|
||||||
|
GraphicsMode ChoosePixelFormatARB(IntPtr device, GraphicsMode mode)
|
||||||
{
|
{
|
||||||
Debug.WriteLine(String.Format("Device context: {0}", device));
|
GraphicsMode created_mode = null;
|
||||||
|
if (Wgl.Delegates.wglChoosePixelFormatARB != null)
|
||||||
|
{
|
||||||
|
List<int> attributes = new List<int>();
|
||||||
|
attributes.Add((int)WGL_ARB_pixel_format.AccelerationArb);
|
||||||
|
attributes.Add((int)WGL_ARB_pixel_format.FullAccelerationArb);
|
||||||
|
|
||||||
Debug.WriteLine("Retrieving PFD pixel formats... ");
|
if (mode.ColorFormat.BitsPerPixel > 0)
|
||||||
|
{
|
||||||
|
attributes.Add((int)WGL_ARB_pixel_format.RedBitsArb);
|
||||||
|
attributes.Add(mode.ColorFormat.Red);
|
||||||
|
attributes.Add((int)WGL_ARB_pixel_format.GreenBitsArb);
|
||||||
|
attributes.Add(mode.ColorFormat.Green);
|
||||||
|
attributes.Add((int)WGL_ARB_pixel_format.BlueBitsArb);
|
||||||
|
attributes.Add(mode.ColorFormat.Blue);
|
||||||
|
attributes.Add((int)WGL_ARB_pixel_format.AlphaBitsArb);
|
||||||
|
attributes.Add(mode.ColorFormat.Alpha);
|
||||||
|
attributes.Add((int)WGL_ARB_pixel_format.ColorBitsArb);
|
||||||
|
attributes.Add(mode.ColorFormat.BitsPerPixel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode.Depth > 0)
|
||||||
|
{
|
||||||
|
attributes.Add((int)WGL_ARB_pixel_format.DepthBitsArb);
|
||||||
|
attributes.Add(mode.Depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode.Stencil > 0)
|
||||||
|
{
|
||||||
|
attributes.Add((int)WGL_ARB_pixel_format.StencilBitsArb);
|
||||||
|
attributes.Add(mode.Stencil);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode.AccumulatorFormat.BitsPerPixel > 0)
|
||||||
|
{
|
||||||
|
attributes.Add((int)WGL_ARB_pixel_format.AccumRedBitsArb);
|
||||||
|
attributes.Add(mode.AccumulatorFormat.Red);
|
||||||
|
attributes.Add((int)WGL_ARB_pixel_format.AccumGreenBitsArb);
|
||||||
|
attributes.Add(mode.AccumulatorFormat.Green);
|
||||||
|
attributes.Add((int)WGL_ARB_pixel_format.AccumBlueBitsArb);
|
||||||
|
attributes.Add(mode.AccumulatorFormat.Blue);
|
||||||
|
attributes.Add((int)WGL_ARB_pixel_format.AccumAlphaBitsArb);
|
||||||
|
attributes.Add(mode.AccumulatorFormat.Alpha);
|
||||||
|
attributes.Add((int)WGL_ARB_pixel_format.AccumBitsArb);
|
||||||
|
attributes.Add(mode.AccumulatorFormat.BitsPerPixel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode.Samples > 0)
|
||||||
|
{
|
||||||
|
attributes.Add((int)WGL_ARB_multisample.SampleBuffersArb);
|
||||||
|
attributes.Add(1);
|
||||||
|
attributes.Add((int)WGL_ARB_multisample.SamplesArb);
|
||||||
|
attributes.Add(mode.Samples);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode.Buffers > 0)
|
||||||
|
{
|
||||||
|
attributes.Add((int)WGL_ARB_pixel_format.DoubleBufferArb);
|
||||||
|
attributes.Add(mode.Buffers);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode.Stereo)
|
||||||
|
{
|
||||||
|
attributes.Add((int)WGL_ARB_pixel_format.StereoArb);
|
||||||
|
attributes.Add(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
attributes.Add(0);
|
||||||
|
attributes.Add(0);
|
||||||
|
|
||||||
|
int[] format = new int[1];
|
||||||
|
int count;
|
||||||
|
if (Wgl.Arb.ChoosePixelFormat(device, attributes.ToArray(), null, format.Length, format, out count))
|
||||||
|
{
|
||||||
|
created_mode = DescribePixelFormatARB(device, format[0]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Print("[WGL] ChoosePixelFormatARB failed with {0}", Marshal.GetLastWin32Error());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Print("[WGL] ChoosePixelFormatARB not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
return created_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ChoosePixelFormatPFD
|
||||||
|
|
||||||
|
GraphicsMode ChoosePixelFormatPFD(IntPtr Device, GraphicsMode mode, AccelerationType requested_acceleration_type)
|
||||||
|
{
|
||||||
PixelFormatDescriptor pfd = new PixelFormatDescriptor();
|
PixelFormatDescriptor pfd = new PixelFormatDescriptor();
|
||||||
pfd.Size = API.PixelFormatDescriptorSize;
|
pfd.Size = (short)BlittableValueType<PixelFormatDescriptor>.Stride;
|
||||||
pfd.Version = API.PixelFormatDescriptorVersion;
|
|
||||||
pfd.Flags =
|
if (mode.ColorFormat.BitsPerPixel > 0)
|
||||||
PixelFormatDescriptorFlags.SUPPORT_OPENGL |
|
{
|
||||||
PixelFormatDescriptorFlags.DRAW_TO_WINDOW;
|
pfd.RedBits = (byte)mode.ColorFormat.Red;
|
||||||
|
pfd.GreenBits = (byte)mode.ColorFormat.Green;
|
||||||
|
pfd.BlueBits = (byte)mode.ColorFormat.Blue;
|
||||||
|
pfd.AlphaBits = (byte)mode.ColorFormat.Alpha;
|
||||||
|
pfd.ColorBits = (byte)mode.ColorFormat.BitsPerPixel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode.Depth > 0)
|
||||||
|
{
|
||||||
|
pfd.DepthBits = (byte)mode.Depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode.Stencil > 0)
|
||||||
|
{
|
||||||
|
pfd.StencilBits = (byte)mode.Stencil;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode.AccumulatorFormat.BitsPerPixel > 0)
|
||||||
|
{
|
||||||
|
pfd.AccumRedBits = (byte)mode.AccumulatorFormat.Red;
|
||||||
|
pfd.AccumGreenBits = (byte)mode.AccumulatorFormat.Green;
|
||||||
|
pfd.AccumBlueBits = (byte)mode.AccumulatorFormat.Blue;
|
||||||
|
pfd.AccumAlphaBits = (byte)mode.AccumulatorFormat.Alpha;
|
||||||
|
pfd.AccumBits = (byte)mode.AccumulatorFormat.BitsPerPixel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode.Buffers > 0)
|
||||||
|
{
|
||||||
|
pfd.Flags |= PixelFormatDescriptorFlags.DOUBLEBUFFER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode.Stereo)
|
||||||
|
{
|
||||||
|
pfd.Flags |= PixelFormatDescriptorFlags.DRAW_TO_WINDOW;
|
||||||
|
pfd.Flags |= PixelFormatDescriptorFlags.SUPPORT_OPENGL;
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure we don't turn off Aero on Vista and newer.
|
// Make sure we don't turn off Aero on Vista and newer.
|
||||||
if (Environment.OSVersion.Version.Major >= 6)
|
if (Environment.OSVersion.Version.Major >= 6)
|
||||||
|
@ -125,109 +241,102 @@ namespace OpenTK.Platform.Windows
|
||||||
pfd.Flags |= PixelFormatDescriptorFlags.SUPPORT_COMPOSITION;
|
pfd.Flags |= PixelFormatDescriptorFlags.SUPPORT_COMPOSITION;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (bool generic_allowed in new bool[] { false, true })
|
GraphicsMode created_mode = null;
|
||||||
|
int pixelformat = Functions.ChoosePixelFormat(Device, ref pfd);
|
||||||
|
if (pixelformat > 0)
|
||||||
{
|
{
|
||||||
// Iterate through all accelerated formats first. Afterwards, iterate through non-accelerated formats.
|
AccelerationType acceleration_type = AccelerationType.ICD;
|
||||||
// This should fix issue #2224, which causes OpenTK to fail on VMs without hardware acceleration.
|
if ((pfd.Flags & PixelFormatDescriptorFlags.GENERIC_FORMAT) != 0)
|
||||||
// Note: DescribePixelFormat found in gdi32 is extremely slow on nvidia, for some reason.
|
|
||||||
int pixel = 0;
|
|
||||||
while (Functions.DescribePixelFormat(device, ++pixel, API.PixelFormatDescriptorSize, ref pfd) != 0)
|
|
||||||
{
|
{
|
||||||
// Ignore non-accelerated formats.
|
if ((pfd.Flags & PixelFormatDescriptorFlags.GENERIC_ACCELERATED) != 0)
|
||||||
if (!generic_allowed && (pfd.Flags & PixelFormatDescriptorFlags.GENERIC_FORMAT) != 0)
|
{
|
||||||
continue;
|
acceleration_type = AccelerationType.MCD;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
acceleration_type = AccelerationType.None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GraphicsMode fmt = new GraphicsMode((IntPtr)pixel,
|
if (acceleration_type == requested_acceleration_type)
|
||||||
new ColorFormat(pfd.RedBits, pfd.GreenBits, pfd.BlueBits, pfd.AlphaBits),
|
{
|
||||||
pfd.DepthBits,
|
created_mode = DescribePixelFormatPFD(ref pfd, pixelformat);
|
||||||
pfd.StencilBits,
|
|
||||||
0,
|
|
||||||
new ColorFormat(pfd.AccumBits),
|
|
||||||
(pfd.Flags & PixelFormatDescriptorFlags.DOUBLEBUFFER) != 0 ? 2 : 1,
|
|
||||||
(pfd.Flags & PixelFormatDescriptorFlags.STEREO) != 0);
|
|
||||||
|
|
||||||
yield return fmt;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return created_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region GetModesARB
|
#region DescribePixelFormatPFD
|
||||||
|
|
||||||
// Queries pixel formats through the WGL_ARB_pixel_format extension
|
static GraphicsMode DescribePixelFormatPFD(ref PixelFormatDescriptor pfd, int pixelformat)
|
||||||
// This method only returns accelerated formats. If no format offers
|
|
||||||
// hardware acceleration (e.g. we are running in a VM or in a remote desktop
|
|
||||||
// connection), this method will return 0 formats and we will fall back to
|
|
||||||
// GetModesPFD.
|
|
||||||
IEnumerable<GraphicsMode> GetModesARB(IntPtr device)
|
|
||||||
{
|
{
|
||||||
// See http://www.opengl.org/registry/specs/ARB/wgl_pixel_format.txt
|
return new GraphicsMode(
|
||||||
// for more details
|
new IntPtr(pixelformat),
|
||||||
Debug.Write("Retrieving ARB pixel formats.... ");
|
new ColorFormat(pfd.RedBits, pfd.GreenBits, pfd.BlueBits, pfd.AlphaBits),
|
||||||
if (Wgl.Delegates.wglChoosePixelFormatARB == null || Wgl.Delegates.wglGetPixelFormatAttribivARB == null)
|
pfd.DepthBits,
|
||||||
|
pfd.StencilBits,
|
||||||
|
0, // MSAA not supported
|
||||||
|
new ColorFormat(pfd.AccumRedBits, pfd.AccumGreenBits, pfd.AccumBlueBits, pfd.AccumAlphaBits),
|
||||||
|
(pfd.Flags & PixelFormatDescriptorFlags.DOUBLEBUFFER) != 0 ? 2 : 1,
|
||||||
|
(pfd.Flags & PixelFormatDescriptorFlags.STEREO) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region DescribePixelFormatARB
|
||||||
|
|
||||||
|
GraphicsMode DescribePixelFormatARB(IntPtr device, int pixelformat)
|
||||||
|
{
|
||||||
|
GraphicsMode created_mode = null;
|
||||||
|
// See http://www.opengl.org/registry/specs/ARB/wgl_pixel_format.txt for more details
|
||||||
|
if (Wgl.Delegates.wglGetPixelFormatAttribivARB != null)
|
||||||
{
|
{
|
||||||
Debug.WriteLine("failed.");
|
// Define the list of attributes we are interested in.
|
||||||
yield break;
|
// The results will be stored in the 'values' array below.
|
||||||
}
|
int[] attribs = new int[]
|
||||||
|
|
||||||
// Define the list of attributes we are interested in.
|
|
||||||
// We will use each available pixel format for these
|
|
||||||
// attributes using GetPixelFormatAttrib.
|
|
||||||
// The results will be stored in the 'values' array below.
|
|
||||||
int[] attribs = new int[]
|
|
||||||
{
|
|
||||||
(int)WGL_ARB_pixel_format.AccelerationArb,
|
|
||||||
|
|
||||||
(int)WGL_ARB_pixel_format.RedBitsArb,
|
|
||||||
(int)WGL_ARB_pixel_format.GreenBitsArb,
|
|
||||||
(int)WGL_ARB_pixel_format.BlueBitsArb,
|
|
||||||
(int)WGL_ARB_pixel_format.AlphaBitsArb,
|
|
||||||
(int)WGL_ARB_pixel_format.ColorBitsArb,
|
|
||||||
|
|
||||||
(int)WGL_ARB_pixel_format.DepthBitsArb,
|
|
||||||
(int)WGL_ARB_pixel_format.StencilBitsArb,
|
|
||||||
|
|
||||||
(int)WGL_ARB_multisample.SampleBuffersArb,
|
|
||||||
(int)WGL_ARB_multisample.SamplesArb,
|
|
||||||
|
|
||||||
(int)WGL_ARB_pixel_format.AccumRedBitsArb,
|
|
||||||
(int)WGL_ARB_pixel_format.AccumGreenBitsArb,
|
|
||||||
(int)WGL_ARB_pixel_format.AccumBlueBitsArb,
|
|
||||||
(int)WGL_ARB_pixel_format.AccumAlphaBitsArb,
|
|
||||||
(int)WGL_ARB_pixel_format.AccumBitsArb,
|
|
||||||
|
|
||||||
(int)WGL_ARB_pixel_format.DoubleBufferArb,
|
|
||||||
(int)WGL_ARB_pixel_format.StereoArb,
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
// Allocate storage for the results of GetPixelFormatAttrib queries
|
|
||||||
int[] values = new int[attribs.Length];
|
|
||||||
|
|
||||||
// Get the number of available formats
|
|
||||||
int num_formats;
|
|
||||||
int num_formats_attrib = (int)WGL_ARB_pixel_format.NumberPixelFormatsArb;
|
|
||||||
if (Wgl.Arb.GetPixelFormatAttrib(device, 0, 0, 1, ref num_formats_attrib, out num_formats))
|
|
||||||
{
|
|
||||||
for (int p = 1; p < num_formats; p++)
|
|
||||||
{
|
{
|
||||||
// Get the format attributes for this pixel format
|
(int)WGL_ARB_pixel_format.AccelerationArb,
|
||||||
if (!Wgl.Arb.GetPixelFormatAttrib(device, p, 0, attribs.Length - 1, attribs, values))
|
|
||||||
{
|
|
||||||
Debug.Print("[Warning] Failed to detect attributes for PixelFormat:{0}.", p);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skip formats that don't offer full hardware acceleration
|
(int)WGL_ARB_pixel_format.RedBitsArb,
|
||||||
WGL_ARB_pixel_format acceleration = (WGL_ARB_pixel_format)attribs[0];
|
(int)WGL_ARB_pixel_format.GreenBitsArb,
|
||||||
if (acceleration != WGL_ARB_pixel_format.FullAccelerationArb)
|
(int)WGL_ARB_pixel_format.BlueBitsArb,
|
||||||
{
|
(int)WGL_ARB_pixel_format.AlphaBitsArb,
|
||||||
continue;
|
(int)WGL_ARB_pixel_format.ColorBitsArb,
|
||||||
}
|
|
||||||
|
(int)WGL_ARB_pixel_format.DepthBitsArb,
|
||||||
|
(int)WGL_ARB_pixel_format.StencilBitsArb,
|
||||||
|
|
||||||
|
(int)WGL_ARB_multisample.SampleBuffersArb,
|
||||||
|
(int)WGL_ARB_multisample.SamplesArb,
|
||||||
|
|
||||||
|
(int)WGL_ARB_pixel_format.AccumRedBitsArb,
|
||||||
|
(int)WGL_ARB_pixel_format.AccumGreenBitsArb,
|
||||||
|
(int)WGL_ARB_pixel_format.AccumBlueBitsArb,
|
||||||
|
(int)WGL_ARB_pixel_format.AccumAlphaBitsArb,
|
||||||
|
(int)WGL_ARB_pixel_format.AccumBitsArb,
|
||||||
|
|
||||||
|
(int)WGL_ARB_pixel_format.DoubleBufferArb,
|
||||||
|
(int)WGL_ARB_pixel_format.StereoArb,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
// Allocate storage for the results of GetPixelFormatAttrib queries
|
||||||
|
int[] values = new int[attribs.Length];
|
||||||
|
|
||||||
|
// Get the format attributes for this pixel format
|
||||||
|
if (!Wgl.Arb.GetPixelFormatAttrib(device, pixelformat, 0, attribs.Length - 1, attribs, values))
|
||||||
|
{
|
||||||
|
Debug.Print("[Warning] Failed to detect attributes for PixelFormat: {0}.", pixelformat);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip formats that don't offer full hardware acceleration
|
||||||
|
WGL_ARB_pixel_format acceleration = (WGL_ARB_pixel_format)attribs[0];
|
||||||
|
if (acceleration == WGL_ARB_pixel_format.FullAccelerationArb)
|
||||||
|
{
|
||||||
// Construct a new GraphicsMode to describe this format
|
// Construct a new GraphicsMode to describe this format
|
||||||
GraphicsMode mode = new GraphicsMode(new IntPtr(p),
|
created_mode = new GraphicsMode(new IntPtr(pixelformat),
|
||||||
new ColorFormat(values[1], values[2], values[3], values[4]),
|
new ColorFormat(values[1], values[2], values[3], values[4]),
|
||||||
values[6],
|
values[6],
|
||||||
values[7],
|
values[7],
|
||||||
|
@ -235,28 +344,9 @@ namespace OpenTK.Platform.Windows
|
||||||
new ColorFormat(values[10], values[11], values[12], values[13]),
|
new ColorFormat(values[10], values[11], values[12], values[13]),
|
||||||
values[15] == 1 ? 2 : 1,
|
values[15] == 1 ? 2 : 1,
|
||||||
values[16] == 1 ? true : false);
|
values[16] == 1 ? true : false);
|
||||||
|
|
||||||
yield return mode;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
return created_mode;
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region ModeSelector
|
|
||||||
|
|
||||||
bool ModeSelector(GraphicsMode current, ColorFormat color, int depth, int stencil, int samples,
|
|
||||||
ColorFormat accum, int buffers, bool stereo)
|
|
||||||
{
|
|
||||||
bool result =
|
|
||||||
(color != ColorFormat.Empty ? current.ColorFormat >= color : true) &&
|
|
||||||
(depth != 0 ? current.Depth >= depth : true) &&
|
|
||||||
(stencil != 0 ? current.Stencil >= stencil : true) &&
|
|
||||||
(samples != 0 ? current.Samples >= samples : true) &&
|
|
||||||
(accum != ColorFormat.Empty ? current.AccumulatorFormat >= accum : true) &&
|
|
||||||
(buffers != 0 ? current.Buffers >= buffers : true) &&
|
|
||||||
current.Stereo == stereo;
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
Loading…
Reference in a new issue