Example #1
0
        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.Stereo)
            {
                flags |= PixelFormatDescriptorFlags.STEREO;
            }

            if (System.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.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
                // 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));
        }
        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));
        }