// Note: there is no relevant ARB function. internal static GraphicsMode SetGraphicsModePFD(WinGraphicsMode mode_selector, GraphicsMode mode, WinWindowInfo window) { Debug.Write("Setting pixel format... "); if (window == null) { throw new ArgumentNullException(nameof(window), "Must point to a valid window."); } if (!mode.Index.HasValue) { mode = mode_selector.SelectGraphicsMode( mode.ColorFormat, mode.Depth, mode.Stencil, mode.Samples, mode.AccumulatorFormat, mode.Buffers, mode.Stereo); } var pfd = new PixelFormatDescriptor(); Gdi32.DescribePixelFormat( window.DeviceContext, (int)mode.Index.Value, PixelFormatDescriptor.SizeInBytes, ref pfd); Debug.WriteLine(mode.Index.ToString()); if (!Gdi32.SetPixelFormat(window.DeviceContext, (int)mode.Index.Value, ref pfd)) { throw new GraphicsContextException( $"Requested GraphicsMode not available. SetPixelFormat error: {Marshal.GetLastWin32Error()}"); } return(mode); }
private static GraphicsMode DescribePixelFormatPFD(IntPtr device, ref PixelFormatDescriptor pfd, int pixelformat) { GraphicsMode created_mode = null; if (Gdi32.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); }
private GraphicsMode ChoosePixelFormatPFD(IntPtr device, GraphicsMode mode, AccelerationType requested_acceleration_type) { var pfd = new PixelFormatDescriptor(); PixelFormatDescriptorFlags flags = 0; flags |= PixelFormatDescriptorFlags.DrawToWindow; flags |= PixelFormatDescriptorFlags.SupportOpenGL; if (mode.Stereo) { flags |= PixelFormatDescriptorFlags.Stereo; } if (Environment.OSVersion.Version.Major >= 6 && requested_acceleration_type != AccelerationType.None) { // Request a compositor-capable mode when running on // Vista+ and using hardware acceleration. Without this, // some modes will cause the compositor to turn off, // which is very annoying to the user. // Note: compositor-capable modes require hardware // acceleration. Don't set this flag when running // with software acceleration (e.g. over Remote Desktop // as described in bug https://github.com/opentk/opentk/issues/35) flags |= PixelFormatDescriptorFlags.SupportComposition; } var count = Gdi32.DescribePixelFormat(device, 1, PixelFormatDescriptor.SizeInBytes, ref pfd); var best = 0; var best_dist = int.MaxValue; for (var index = 1; index <= count; index++) { var dist = 0; var valid = Gdi32.DescribePixelFormat(device, index, PixelFormatDescriptor.SizeInBytes, ref pfd) != 0; valid &= GetAccelerationType(ref pfd) == requested_acceleration_type; valid &= (pfd.Flags & flags) == flags; valid &= pfd.PixelType == PixelFormatDescriptorPixelTypes.Rgba; // indexed modes not currently supported // heavily penalize single-buffered modes when the user requests double buffering if ((pfd.Flags & PixelFormatDescriptorFlags.DoubleBuffer) == 0 && mode.Buffers > 1) { dist += 1000; } 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)); }