attributes.Add((int)WGL_ARB_pixel_format.AccelerationArb);
attributes.Add((int)WGL_ARB_pixel_format.FullAccelerationArb);
- if (mode.ColorFormat.BitsPerPixel > 0)
+ if (mode.ColorFormat.Red > 0)
{
attributes.Add((int)WGL_ARB_pixel_format.RedBitsArb);
attributes.Add(mode.ColorFormat.Red);
+ }
+
+ if (mode.ColorFormat.Green > 0)
+ {
attributes.Add((int)WGL_ARB_pixel_format.GreenBitsArb);
attributes.Add(mode.ColorFormat.Green);
+ }
+
+ if (mode.ColorFormat.Blue > 0)
+ {
attributes.Add((int)WGL_ARB_pixel_format.BlueBitsArb);
attributes.Add(mode.ColorFormat.Blue);
+ }
+
+ if (mode.ColorFormat.Alpha > 0)
+ {
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(mode.Stencil);
}
- if (mode.AccumulatorFormat.BitsPerPixel > 0)
+ if (mode.AccumulatorFormat.Red > 0)
{
attributes.Add((int)WGL_ARB_pixel_format.AccumRedBitsArb);
attributes.Add(mode.AccumulatorFormat.Red);
+ }
+
+ if (mode.AccumulatorFormat.Green > 0)
+ {
attributes.Add((int)WGL_ARB_pixel_format.AccumGreenBitsArb);
attributes.Add(mode.AccumulatorFormat.Green);
+ }
+
+ if (mode.AccumulatorFormat.Blue > 0)
+ {
attributes.Add((int)WGL_ARB_pixel_format.AccumBlueBitsArb);
attributes.Add(mode.AccumulatorFormat.Blue);
+ }
+
+ if (mode.AccumulatorFormat.Alpha > 0)
+ {
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)
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);
}
else
{
- Debug.Print("[WGL] ChoosePixelFormatARB not supported");
+ Debug.WriteLine("[WGL] ChoosePixelFormatARB not supported on this context");
}
return created_mode;
#region ChoosePixelFormatPFD
- GraphicsMode ChoosePixelFormatPFD(IntPtr device, GraphicsMode mode, AccelerationType requested_acceleration_type)
+ static bool Compare(int got, int requested, ref int distance)
{
- PixelFormatDescriptor pfd = new PixelFormatDescriptor();
- pfd.Size = (short)BlittableValueType<PixelFormatDescriptor>.Stride;
-
- if (mode.ColorFormat.BitsPerPixel > 0)
- {
- 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)
+ if (got < requested)
{
- pfd.DepthBits = (byte)mode.Depth;
+ return false;
}
else
{
- pfd.Flags |= PixelFormatDescriptorFlags.DEPTH_DONTCARE;
+ distance += got - requested;
+ return true;
}
+ }
- if (mode.Stencil > 0)
+ static AccelerationType GetAccelerationType(ref PixelFormatDescriptor pfd)
+ {
+ AccelerationType type = AccelerationType.ICD;
+ if ((pfd.Flags & PixelFormatDescriptorFlags.GENERIC_FORMAT) != 0)
{
- pfd.StencilBits = (byte)mode.Stencil;
+ if ((pfd.Flags & PixelFormatDescriptorFlags.GENERIC_ACCELERATED) != 0)
+ {
+ type = AccelerationType.MCD;
+ }
+ else
+ {
+ type = AccelerationType.None;
+ }
}
+ return type;
+ }
- 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;
- }
+ GraphicsMode ChoosePixelFormatPFD(IntPtr device, GraphicsMode mode, AccelerationType requested_acceleration_type)
+ {
+ PixelFormatDescriptor pfd = new PixelFormatDescriptor();
+ PixelFormatDescriptorFlags flags = 0;
+ flags |= PixelFormatDescriptorFlags.DRAW_TO_WINDOW;
+ flags |= PixelFormatDescriptorFlags.SUPPORT_OPENGL;
- if (mode.Buffers > 1)
+ if (mode.Stereo)
{
- pfd.Flags |= PixelFormatDescriptorFlags.DOUBLEBUFFER;
+ flags |= PixelFormatDescriptorFlags.STEREO;
}
- else if (mode.Buffers == 0)
+ if (mode.Buffers > 1)
{
- pfd.Flags |= PixelFormatDescriptorFlags.DOUBLEBUFFER_DONTCARE;
+ // On Win7 64bit + Nvidia 650M, no pixel format advertises DOUBLEBUFFER.
+ // Adding this check here causes mode selection to fail.
+ // Does not appear to be supported by DescribePixelFormat
+ //flags |= PixelFormatDescriptorFlags.DOUBLEBUFFER;
}
-
- if (mode.Stereo)
+ if (System.Environment.OSVersion.Version.Major >= 6)
{
- pfd.Flags |= PixelFormatDescriptorFlags.DRAW_TO_WINDOW;
- pfd.Flags |= PixelFormatDescriptorFlags.SUPPORT_OPENGL;
+ flags |= PixelFormatDescriptorFlags.SUPPORT_COMPOSITION;
}
- // Make sure we don't turn off Aero on Vista and newer.
- if (Environment.OSVersion.Version.Major >= 6)
- {
- pfd.Flags |= PixelFormatDescriptorFlags.SUPPORT_COMPOSITION;
- }
+ int count = Functions.DescribePixelFormat(device, 1, API.PixelFormatDescriptorSize, ref pfd);
- GraphicsMode created_mode = null;
- int pixelformat = Functions.ChoosePixelFormat(device, ref pfd);
- if (pixelformat > 0)
+ int best = 0;
+ int best_dist = int.MaxValue;
+ for (int index = 1; index <= count; index++)
{
- AccelerationType acceleration_type = AccelerationType.ICD;
- if ((pfd.Flags & PixelFormatDescriptorFlags.GENERIC_FORMAT) != 0)
- {
- if ((pfd.Flags & PixelFormatDescriptorFlags.GENERIC_ACCELERATED) != 0)
- {
- acceleration_type = AccelerationType.MCD;
- }
- else
- {
- acceleration_type = AccelerationType.None;
- }
- }
-
- if (acceleration_type == requested_acceleration_type)
+ int dist = 0;
+ bool valid = Functions.DescribePixelFormat(device, index, API.PixelFormatDescriptorSize, ref pfd) != 0;
+ valid &= GetAccelerationType(ref pfd) == requested_acceleration_type;
+ valid &= (pfd.Flags & flags) == flags;
+ valid &= pfd.PixelType == PixelType.RGBA; // indexed modes not currently supported
+ valid &= Compare(pfd.ColorBits, mode.ColorFormat.BitsPerPixel, ref dist);
+ valid &= Compare(pfd.RedBits, mode.ColorFormat.Red, ref dist);
+ valid &= Compare(pfd.GreenBits, mode.ColorFormat.Green, ref dist);
+ valid &= Compare(pfd.BlueBits, mode.ColorFormat.Blue, ref dist);
+ valid &= Compare(pfd.AlphaBits, mode.ColorFormat.Alpha, ref dist);
+ valid &= Compare(pfd.AccumBits, mode.AccumulatorFormat.BitsPerPixel, ref dist);
+ valid &= Compare(pfd.AccumRedBits, mode.AccumulatorFormat.Red, ref dist);
+ valid &= Compare(pfd.AccumGreenBits, mode.AccumulatorFormat.Green, ref dist);
+ valid &= Compare(pfd.AccumBlueBits, mode.AccumulatorFormat.Blue, ref dist);
+ valid &= Compare(pfd.AccumAlphaBits, mode.AccumulatorFormat.Alpha, ref dist);
+ valid &= Compare(pfd.DepthBits, mode.Depth, ref dist);
+ valid &= Compare(pfd.StencilBits, mode.Stencil, ref dist);
+
+ if (valid && dist < best_dist)
{
- created_mode = DescribePixelFormatPFD(device, ref pfd, pixelformat);
+ best = index;
+ best_dist = dist;
}
}
- return created_mode;
+
+ return DescribePixelFormatPFD(device, ref pfd, best);
}
#endregion
#region DescribePixelFormatPFD
- static GraphicsMode DescribePixelFormatPFD(IntPtr device, ref PixelFormatDescriptor pfd, int pixelformat)
+ static GraphicsMode DescribePixelFormatPFD(IntPtr device, ref PixelFormatDescriptor pfd,
+ int pixelformat)
{
GraphicsMode created_mode = null;
if (Functions.DescribePixelFormat(device, pixelformat, pfd.Size, ref pfd) > 0)
}
// Skip formats that don't offer full hardware acceleration
- WGL_ARB_pixel_format acceleration = (WGL_ARB_pixel_format)attribs[0];
+ WGL_ARB_pixel_format acceleration = (WGL_ARB_pixel_format)values[0];
if (acceleration == WGL_ARB_pixel_format.FullAccelerationArb)
{
// Construct a new GraphicsMode to describe this format