mirror of
https://github.com/Ryujinx/Opentk.git
synced 2025-01-11 05:45:57 +00:00
Merge branch 'wgl_issue21'. Fixes issue #21
This commit is contained in:
commit
838adc0afc
|
@ -218,7 +218,10 @@ namespace Examples.Tests
|
||||||
|
|
||||||
gfx.Clear(Color.Black);
|
gfx.Clear(Color.Black);
|
||||||
gfx.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
|
gfx.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
|
||||||
|
|
||||||
|
DrawString(gfx, GL.GetString(StringName.Vendor), line++);
|
||||||
|
DrawString(gfx, GL.GetString(StringName.Version), line++);
|
||||||
|
DrawString(gfx, GL.GetString(StringName.Renderer), line++);
|
||||||
DrawString(gfx, Context.GraphicsMode.ToString(), line++);
|
DrawString(gfx, Context.GraphicsMode.ToString(), line++);
|
||||||
|
|
||||||
DrawString(gfx, String.Format("[1 - 4]: change WindowState (current: {0}).", this.WindowState), line++);
|
DrawString(gfx, String.Format("[1 - 4]: change WindowState (current: {0}).", this.WindowState), line++);
|
||||||
|
|
|
@ -202,14 +202,14 @@ namespace OpenTK.Platform.Windows
|
||||||
}
|
}
|
||||||
|
|
||||||
public static
|
public static
|
||||||
Boolean ChoosePixelFormat(IntPtr hdc, int[] piAttribIList, Single[] pfAttribFList, Int32 nMaxFormats, [Out] int[] piFormats, [Out] Int32[] nNumFormats)
|
Boolean ChoosePixelFormat(IntPtr hdc, int[] piAttribIList, Single[] pfAttribFList, Int32 nMaxFormats, [Out] int[] piFormats, out int nNumFormats)
|
||||||
{
|
{
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
fixed (int* piAttribIList_ptr = piAttribIList)
|
fixed (int* piAttribIList_ptr = piAttribIList)
|
||||||
fixed (Single* pfAttribFList_ptr = pfAttribFList)
|
fixed (Single* pfAttribFList_ptr = pfAttribFList)
|
||||||
fixed (int* piFormats_ptr = piFormats)
|
fixed (int* piFormats_ptr = piFormats)
|
||||||
fixed (Int32* nNumFormats_ptr = nNumFormats)
|
fixed (Int32* nNumFormats_ptr = &nNumFormats)
|
||||||
{
|
{
|
||||||
return Delegates.wglChoosePixelFormatARB((IntPtr)hdc, (int*)piAttribIList_ptr, (Single*)pfAttribFList_ptr, (UInt32)nMaxFormats, (int*)piFormats_ptr, (UInt32*)nNumFormats_ptr);
|
return Delegates.wglChoosePixelFormatARB((IntPtr)hdc, (int*)piAttribIList_ptr, (Single*)pfAttribFList_ptr, (UInt32)nMaxFormats, (int*)piFormats_ptr, (UInt32*)nNumFormats_ptr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -279,14 +279,14 @@ namespace OpenTK.Platform.Windows
|
||||||
throw new ArgumentException("window", "Must point to a valid window.");
|
throw new ArgumentException("window", "Must point to a valid window.");
|
||||||
|
|
||||||
success = Wgl.MakeCurrent(wnd.DeviceContext, Handle.Handle);
|
success = Wgl.MakeCurrent(wnd.DeviceContext, Handle.Handle);
|
||||||
|
device_context = wnd.DeviceContext;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
success = Wgl.MakeCurrent(IntPtr.Zero, IntPtr.Zero);
|
success = Wgl.MakeCurrent(IntPtr.Zero, IntPtr.Zero);
|
||||||
|
device_context = IntPtr.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
device_context = wnd.DeviceContext;
|
|
||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
throw new GraphicsContextException(String.Format(
|
throw new GraphicsContextException(String.Format(
|
||||||
|
|
|
@ -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,167 +68,316 @@ 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)
|
|
||||||
{
|
|
||||||
Debug.WriteLine(String.Format("Device context: {0}", device));
|
|
||||||
|
|
||||||
Debug.WriteLine("Retrieving PFD pixel formats... ");
|
|
||||||
PixelFormatDescriptor pfd = new PixelFormatDescriptor();
|
|
||||||
pfd.Size = API.PixelFormatDescriptorSize;
|
|
||||||
pfd.Version = API.PixelFormatDescriptorVersion;
|
|
||||||
pfd.Flags =
|
|
||||||
PixelFormatDescriptorFlags.SUPPORT_OPENGL |
|
|
||||||
PixelFormatDescriptorFlags.DRAW_TO_WINDOW;
|
|
||||||
|
|
||||||
// Make sure we don't turn off Aero on Vista and newer.
|
|
||||||
if (Environment.OSVersion.Version.Major >= 6)
|
|
||||||
{
|
|
||||||
pfd.Flags |= PixelFormatDescriptorFlags.SUPPORT_COMPOSITION;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (bool generic_allowed in new bool[] { false, true })
|
|
||||||
{
|
|
||||||
// Iterate through all accelerated formats first. Afterwards, iterate through non-accelerated formats.
|
|
||||||
// This should fix issue #2224, which causes OpenTK to fail on VMs without hardware acceleration.
|
|
||||||
// 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 (!generic_allowed && (pfd.Flags & PixelFormatDescriptorFlags.GENERIC_FORMAT) != 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
GraphicsMode fmt = new GraphicsMode((IntPtr)pixel,
|
|
||||||
new ColorFormat(pfd.RedBits, pfd.GreenBits, pfd.BlueBits, pfd.AlphaBits),
|
|
||||||
pfd.DepthBits,
|
|
||||||
pfd.StencilBits,
|
|
||||||
0,
|
|
||||||
new ColorFormat(pfd.AccumBits),
|
|
||||||
(pfd.Flags & PixelFormatDescriptorFlags.DOUBLEBUFFER) != 0 ? 2 : 1,
|
|
||||||
(pfd.Flags & PixelFormatDescriptorFlags.STEREO) != 0);
|
|
||||||
|
|
||||||
yield return fmt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region GetModesARB
|
|
||||||
|
|
||||||
// Queries pixel formats through the WGL_ARB_pixel_format extension
|
// Queries pixel formats through the WGL_ARB_pixel_format extension
|
||||||
// This method only returns accelerated formats. If no format offers
|
// 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
|
// 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
|
// connection), this method will return 0 formats and we will fall back to
|
||||||
// GetModesPFD.
|
// ChoosePixelFormatPFD.
|
||||||
IEnumerable<GraphicsMode> GetModesARB(IntPtr device)
|
GraphicsMode ChoosePixelFormatARB(IntPtr device, GraphicsMode mode)
|
||||||
{
|
{
|
||||||
// See http://www.opengl.org/registry/specs/ARB/wgl_pixel_format.txt
|
GraphicsMode created_mode = null;
|
||||||
// for more details
|
if (Wgl.Delegates.wglChoosePixelFormatARB != null)
|
||||||
Debug.Write("Retrieving ARB pixel formats.... ");
|
|
||||||
if (Wgl.Delegates.wglChoosePixelFormatARB == null || Wgl.Delegates.wglGetPixelFormatAttribivARB == null)
|
|
||||||
{
|
{
|
||||||
Debug.WriteLine("failed.");
|
List<int> attributes = new List<int>();
|
||||||
yield break;
|
attributes.Add((int)WGL_ARB_pixel_format.AccelerationArb);
|
||||||
|
attributes.Add((int)WGL_ARB_pixel_format.FullAccelerationArb);
|
||||||
|
|
||||||
|
attributes.Add((int)WGL_ARB_pixel_format.DrawToWindowArb);
|
||||||
|
attributes.Add(1);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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.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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 > 1 ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
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.WriteLine("[WGL] ChoosePixelFormatARB not supported on this context");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define the list of attributes we are interested in.
|
return created_mode;
|
||||||
// We will use each available pixel format for these
|
}
|
||||||
// attributes using GetPixelFormatAttrib.
|
|
||||||
// The results will be stored in the 'values' array below.
|
#endregion
|
||||||
int[] attribs = new int[]
|
|
||||||
|
#region ChoosePixelFormatPFD
|
||||||
|
|
||||||
|
static bool Compare(int got, int requested, ref int distance)
|
||||||
|
{
|
||||||
|
if (got < requested)
|
||||||
{
|
{
|
||||||
(int)WGL_ARB_pixel_format.AccelerationArb,
|
return false;
|
||||||
|
}
|
||||||
(int)WGL_ARB_pixel_format.RedBitsArb,
|
else
|
||||||
(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++)
|
distance += got - requested;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static AccelerationType GetAccelerationType(ref PixelFormatDescriptor pfd)
|
||||||
|
{
|
||||||
|
AccelerationType type = AccelerationType.ICD;
|
||||||
|
if ((pfd.Flags & PixelFormatDescriptorFlags.GENERIC_FORMAT) != 0)
|
||||||
|
{
|
||||||
|
if ((pfd.Flags & PixelFormatDescriptorFlags.GENERIC_ACCELERATED) != 0)
|
||||||
{
|
{
|
||||||
// Get the format attributes for this pixel format
|
type = AccelerationType.MCD;
|
||||||
if (!Wgl.Arb.GetPixelFormatAttrib(device, p, 0, attribs.Length - 1, attribs, values))
|
}
|
||||||
{
|
else
|
||||||
Debug.Print("[Warning] Failed to detect attributes for PixelFormat:{0}.", p);
|
{
|
||||||
continue;
|
type = AccelerationType.None;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
// Skip formats that don't offer full hardware acceleration
|
GraphicsMode ChoosePixelFormatPFD(IntPtr device, GraphicsMode mode, AccelerationType requested_acceleration_type)
|
||||||
WGL_ARB_pixel_format acceleration = (WGL_ARB_pixel_format)attribs[0];
|
{
|
||||||
if (acceleration != WGL_ARB_pixel_format.FullAccelerationArb)
|
PixelFormatDescriptor pfd = new PixelFormatDescriptor();
|
||||||
{
|
PixelFormatDescriptorFlags flags = 0;
|
||||||
continue;
|
flags |= PixelFormatDescriptorFlags.DRAW_TO_WINDOW;
|
||||||
}
|
flags |= PixelFormatDescriptorFlags.SUPPORT_OPENGL;
|
||||||
|
|
||||||
|
if (mode.Stereo)
|
||||||
|
{
|
||||||
|
flags |= PixelFormatDescriptorFlags.STEREO;
|
||||||
|
}
|
||||||
|
if (mode.Buffers > 1)
|
||||||
|
{
|
||||||
|
// 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 (System.Environment.OSVersion.Version.Major >= 6)
|
||||||
|
{
|
||||||
|
flags |= PixelFormatDescriptorFlags.SUPPORT_COMPOSITION;
|
||||||
|
}
|
||||||
|
|
||||||
|
int count = Functions.DescribePixelFormat(device, 1, API.PixelFormatDescriptorSize, ref pfd);
|
||||||
|
|
||||||
|
int best = 0;
|
||||||
|
int best_dist = int.MaxValue;
|
||||||
|
for (int index = 1; index <= count; index++)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
best = index;
|
||||||
|
best_dist = dist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return DescribePixelFormatPFD(device, ref pfd, best);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region DescribePixelFormatPFD
|
||||||
|
|
||||||
|
static GraphicsMode DescribePixelFormatPFD(IntPtr device, ref PixelFormatDescriptor pfd,
|
||||||
|
int pixelformat)
|
||||||
|
{
|
||||||
|
GraphicsMode created_mode = null;
|
||||||
|
if (Functions.DescribePixelFormat(device, pixelformat, pfd.Size, ref pfd) > 0)
|
||||||
|
{
|
||||||
|
created_mode = new GraphicsMode(
|
||||||
|
new IntPtr(pixelformat),
|
||||||
|
new ColorFormat(pfd.RedBits, pfd.GreenBits, pfd.BlueBits, pfd.AlphaBits),
|
||||||
|
pfd.DepthBits,
|
||||||
|
pfd.StencilBits,
|
||||||
|
0, // MSAA not supported when using PixelFormatDescriptor
|
||||||
|
new ColorFormat(pfd.AccumRedBits, pfd.AccumGreenBits, pfd.AccumBlueBits, pfd.AccumAlphaBits),
|
||||||
|
(pfd.Flags & PixelFormatDescriptorFlags.DOUBLEBUFFER) != 0 ? 2 : 1,
|
||||||
|
(pfd.Flags & PixelFormatDescriptorFlags.STEREO) != 0);
|
||||||
|
}
|
||||||
|
return created_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
#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)
|
||||||
|
{
|
||||||
|
// Define the list of attributes we are interested in.
|
||||||
|
// 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 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)values[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 +385,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