Example #1
0
        /// <summary>
        /// Finds the index of the supported pixel format closest to the requested pixel format.
        /// </summary>
        /// <param name="dc">The window's handle.</param>
        /// <returns>The index of the pixel format to use.</returns>
        private static int SupportedPixelFormat(IntPtr dc)
        {
            var usableConfigs = new List <FramebufferConfig>();

            // Get the number of formats.
            int nativeCount = Gdi32.DescribePixelFormat(dc, 1, (uint)sizeof(PixelFormatDescriptor), IntPtr.Zero);

            for (var i = 0; i < nativeCount; i++)
            {
                var fbConfig = new FramebufferConfig();

                var pfd = new PixelFormatDescriptor();
                pfd.NSize = (ushort)Marshal.SizeOf(pfd);
                if (Gdi32.DescribePixelFormat(dc, i + 1, (uint)sizeof(PixelFormatDescriptor), ref pfd) == 0)
                {
                    Win32Platform.CheckError("Gallium: Could not describe pixel format.", true);
                    continue;
                }

                // We need both of these to be supported.
                if ((pfd.DwFlags & PixelFormatFlags.DrawToWindow) == 0 ||
                    (pfd.DwFlags & PixelFormatFlags.SupportOpenGl) == 0)
                {
                    continue;
                }

                // Should be GenericAccelerated, and mustn't be generic.
                if ((pfd.DwFlags & PixelFormatFlags.GenericAccelerated) == 0 &&
                    (pfd.DwFlags & PixelFormatFlags.Generic) != 0)
                {
                    continue;
                }

                if (pfd.PixelType != (byte)PixelFormatFlags.RGBA)
                {
                    continue;
                }

                fbConfig.RedBits   = pfd.CRedBits;
                fbConfig.GreenBits = pfd.CGreenBits;
                fbConfig.BlueBits  = pfd.CBlueBits;
                fbConfig.AlphaBits = pfd.CAlphaBits;

                fbConfig.DepthBits   = pfd.CDepthBits;
                fbConfig.StencilBits = pfd.CStencilBits;

                fbConfig.AccumRedBits   = pfd.CAccumRedBits;
                fbConfig.AccumGreenBits = pfd.CAccumGreenBits;
                fbConfig.AccumBlueBits  = pfd.CAccumBlueBits;
                fbConfig.AccumAlphaBits = pfd.CAccumAlphaBits;

                if ((pfd.DwFlags & PixelFormatFlags.Stereo) != 0)
                {
                    fbConfig.Stereo = true;
                }

                if ((pfd.DwFlags & PixelFormatFlags.DoubleBuffer) != 0)
                {
                    fbConfig.Doublebuffer = true;
                }

                fbConfig.Handle = i + 1;
                usableConfigs.Add(fbConfig);
            }

            if (usableConfigs.Count == 0)
            {
                Engine.Log.Error("The driver doesn't seem to support OpenGL.", MessageSource.WGallium);
                return(0);
            }

            FramebufferConfig closestConfig = ChoosePixelFormat(usableConfigs);

            if (closestConfig != null)
            {
                return(closestConfig.Handle);
            }

            Engine.Log.Error("Couldn't find suitable pixel format.", MessageSource.WGallium);
            return(0);
        }
Example #2
0
        /// <summary>
        /// Finds the index of the supported pixel format closest to the requested pixel format.
        /// </summary>
        /// <returns>The index of the pixel format to use.</returns>
        private int SupportedPixelFormat(IntPtr[] configs)
        {
            var usableConfigs  = new List <FramebufferConfig>();
            var attributeValue = 0;

            for (var i = 0; i < configs.Length; i++)
            {
                IntPtr currentConfig = configs[i];

                // We only want RGB buffers.
                if (!Egl.GetConfigAttribute(_display, currentConfig, Egl.ConfigAttribute.EGL_COLOR_BUFFER_TYPE, ref attributeValue))
                {
                    continue;
                }
                if (attributeValue != (int)Egl.ConfigValue.EGL_RGB_BUFFER)
                {
                    continue;
                }

                // We only want window type configs.
                // EGL_WINDOW_BIT 0x0004
                Egl.GetConfigAttribute(_display, currentConfig, Egl.ConfigAttribute.EGL_SURFACE_TYPE, ref attributeValue);
                if ((attributeValue & 0x0004) == 0)
                {
                    continue;
                }

                // We want configs that support ES2 (We actually want ES3, but there's no such bit)
                // EGL_OPENGL_ES2_BIT 0x0004
                Egl.GetConfigAttribute(_display, currentConfig, Egl.ConfigAttribute.EGL_RENDERABLE_TYPE, ref attributeValue);
                if ((attributeValue & 0x0004) == 0)
                {
                    continue;
                }

                var fbConfig = new FramebufferConfig();

                Egl.GetConfigAttribute(_display, currentConfig, Egl.ConfigAttribute.EGL_RED_SIZE, ref attributeValue);
                fbConfig.RedBits = attributeValue;

                Egl.GetConfigAttribute(_display, currentConfig, Egl.ConfigAttribute.EGL_GREEN_SIZE, ref attributeValue);
                fbConfig.GreenBits = attributeValue;

                Egl.GetConfigAttribute(_display, currentConfig, Egl.ConfigAttribute.EGL_BLUE_SIZE, ref attributeValue);
                fbConfig.BlueBits = attributeValue;

                Egl.GetConfigAttribute(_display, currentConfig, Egl.ConfigAttribute.EGL_ALPHA_SIZE, ref attributeValue);
                fbConfig.AlphaBits = attributeValue;

                Egl.GetConfigAttribute(_display, currentConfig, Egl.ConfigAttribute.EGL_DEPTH_SIZE, ref attributeValue);
                fbConfig.DepthBits = attributeValue;

                Egl.GetConfigAttribute(_display, currentConfig, Egl.ConfigAttribute.EGL_STENCIL_SIZE, ref attributeValue);
                fbConfig.StencilBits = attributeValue;

                Egl.GetConfigAttribute(_display, currentConfig, Egl.ConfigAttribute.EGL_SAMPLES, ref attributeValue);
                fbConfig.Samples      = attributeValue;
                fbConfig.Doublebuffer = true;

                fbConfig.Handle = i + 1;
                usableConfigs.Add(fbConfig);
            }

            if (usableConfigs.Count == 0)
            {
                Engine.Log.Error("The driver doesn't seem to support OpenGL.", MessageSource.WGallium);
                return(0);
            }

            FramebufferConfig closestConfig = ChoosePixelFormat(usableConfigs);

            if (closestConfig != null)
            {
                return(closestConfig.Handle);
            }

            Engine.Log.Error("Couldn't find suitable pixel format.", MessageSource.WGallium);
            return(0);
        }
Example #3
0
        /// <summary>
        /// Finds the index of the supported pixel format closest to the requested pixel format.
        /// </summary>
        /// <param name="dc">The window's handle.</param>
        /// <returns>The index of the pixel format to use.</returns>
        private int SupportedPixelFormat(IntPtr dc)
        {
            var nativeCount   = 0;
            var usableConfigs = new List <FramebufferConfig>();

            // Check whether we can use the modern API or not.
            if (_arbPixelFormat)
            {
                if (_getPixelFormatAttribivArb == null)
                {
                    throw new Exception("WGL: Unsupported graphics context, getPixelFormatAttribivArb is missing!");
                }

                int nPf = FLAG_NUMBER_PIXEL_FORMATS_ARB;
                if (!_getPixelFormatAttribivArb(dc, 1, 0, 1, &nPf, &nativeCount))
                {
                    Win32Platform.CheckError("WGL: Failed to retrieve pixel format attribute.", true);
                    return(0);
                }

                var foundAttributes = new List <int>
                {
                    (int)WglAttributes.SupportOpenGLArb,
                    (int)WglAttributes.DrawToWindowArb,
                    (int)WglAttributes.PixelTypeArb,
                    (int)WglAttributes.AccelerationArb,
                    (int)WglAttributes.RedBitsArb,
                    (int)WglAttributes.RedShiftArb,
                    (int)WglAttributes.GreenBitsArb,
                    (int)WglAttributes.GreenShiftArb,
                    (int)WglAttributes.BlueBitsArb,
                    (int)WglAttributes.BlueShiftArb,
                    (int)WglAttributes.AlphaBitsArb,
                    (int)WglAttributes.AlphaShiftArb,
                    (int)WglAttributes.DepthBitsArb,
                    (int)WglAttributes.StencilBitsArb,
                    (int)WglAttributes.AccumBitsArb,
                    (int)WglAttributes.AccumRedBitsArb,
                    (int)WglAttributes.AccumGreenBitsArb,
                    (int)WglAttributes.AccumBlueBitsArb,
                    (int)WglAttributes.AccumAlphaBitsArb,
                    (int)WglAttributes.AuxBuffersArb,
                    (int)WglAttributes.StereoArb,
                    (int)WglAttributes.DoubleBufferArb
                };

                if (_arbMultisample)
                {
                    foundAttributes.Add((int)WglAttributes.SamplesArb);
                }

                if (_arbFramebufferSRgb || _extFramebufferSRgb)
                {
                    foundAttributes.Add((int)WglAttributes.FramebufferSrgbCapableArb);
                }

                int[] attributes = foundAttributes.ToArray();

                for (var i = 0; i < nativeCount; i++)
                {
                    var fbConfig = new FramebufferConfig();

                    // Get pixel format attributes through "modern" extension
                    var values = new int[attributes.Length];

                    fixed(int *vPtr = &values[0])
                    {
                        fixed(int *attrPtr = &attributes[0])
                        {
                            if (!_getPixelFormatAttribivArb(dc, i + 1, 0, (uint)attributes.Length, attrPtr, vPtr))
                            {
                                Win32Platform.CheckError($"WGL: Failed to retrieve pixel format attribute - for config {i}.", true);
                                return(0);
                            }
                        }
                    }

                    if (FindAttributeValue(attributes, values, WglAttributes.SupportOpenGLArb) == 0 ||
                        FindAttributeValue(attributes, values, WglAttributes.DrawToWindowArb) == 0)
                    {
                        continue;
                    }

                    if (FindAttributeValue(attributes, values, WglAttributes.PixelTypeArb) != (int)WglAttributeValues.TypeRgbaArb)
                    {
                        continue;
                    }
                    if (FindAttributeValue(attributes, values, WglAttributes.AccelerationArb) == (int)WglAttributeValues.NoAccelerationArb)
                    {
                        continue;
                    }

                    fbConfig.RedBits   = FindAttributeValue(attributes, values, WglAttributes.RedBitsArb);
                    fbConfig.GreenBits = FindAttributeValue(attributes, values, WglAttributes.GreenBitsArb);
                    fbConfig.BlueBits  = FindAttributeValue(attributes, values, WglAttributes.BlueBitsArb);
                    fbConfig.AlphaBits = FindAttributeValue(attributes, values, WglAttributes.AlphaBitsArb);

                    fbConfig.DepthBits   = FindAttributeValue(attributes, values, WglAttributes.DepthBitsArb);
                    fbConfig.StencilBits = FindAttributeValue(attributes, values, WglAttributes.StencilBitsArb);

                    fbConfig.AccumRedBits   = FindAttributeValue(attributes, values, WglAttributes.AccumRedBitsArb);
                    fbConfig.AccumGreenBits = FindAttributeValue(attributes, values, WglAttributes.AccumGreenBitsArb);
                    fbConfig.AccumBlueBits  = FindAttributeValue(attributes, values, WglAttributes.AccumBlueBitsArb);
                    fbConfig.AccumAlphaBits = FindAttributeValue(attributes, values, WglAttributes.AccumAlphaBitsArb);

                    fbConfig.AuxBuffers = FindAttributeValue(attributes, values, WglAttributes.AuxBuffersArb);

                    fbConfig.Stereo       = FindAttributeValue(attributes, values, WglAttributes.StereoArb) != 0;
                    fbConfig.Doublebuffer = FindAttributeValue(attributes, values, WglAttributes.DoubleBufferArb) != 0;

                    if (_arbMultisample)
                    {
                        fbConfig.Samples = FindAttributeValue(attributes, values, WglAttributes.SamplesArb);
                    }

                    if (_arbFramebufferSRgb ||
                        _extFramebufferSRgb)
                    {
                        if (FindAttributeValue(attributes, values, WglAttributes.FramebufferSrgbCapableArb) != 0)
                        {
                            fbConfig.SRgb = true;
                        }
                    }

                    fbConfig.Handle = i + 1;
                    usableConfigs.Add(fbConfig);
                }
            }
            else
            {
                nativeCount = Gdi32.DescribePixelFormat(dc, 1, (uint)sizeof(PixelFormatDescriptor), IntPtr.Zero);

                for (var i = 0; i < nativeCount; i++)
                {
                    var fbConfig = new FramebufferConfig();

                    var pfd = new PixelFormatDescriptor();
                    pfd.NSize = (ushort)Marshal.SizeOf(pfd);
                    if (Gdi32.DescribePixelFormat(dc, i + 1, (uint)sizeof(PixelFormatDescriptor), ref pfd) == 0)
                    {
                        Win32Platform.CheckError("WGL: Could not describe pixel format.", true);
                        continue;
                    }

                    // We need both of these to be supported.
                    if ((pfd.DwFlags & PixelFormatFlags.DrawToWindow) == 0 ||
                        (pfd.DwFlags & PixelFormatFlags.SupportOpenGl) == 0)
                    {
                        continue;
                    }

                    // Should be GenericAccelerated, and mustn't be generic.
                    if ((pfd.DwFlags & PixelFormatFlags.GenericAccelerated) == 0 &&
                        (pfd.DwFlags & PixelFormatFlags.Generic) != 0)
                    {
                        continue;
                    }

                    if (pfd.PixelType != (byte)PixelFormatFlags.RGBA)
                    {
                        continue;
                    }

                    fbConfig.RedBits   = pfd.CRedBits;
                    fbConfig.GreenBits = pfd.CGreenBits;
                    fbConfig.BlueBits  = pfd.CBlueBits;
                    fbConfig.AlphaBits = pfd.CAlphaBits;

                    fbConfig.DepthBits   = pfd.CDepthBits;
                    fbConfig.StencilBits = pfd.CStencilBits;

                    fbConfig.AccumRedBits   = pfd.CAccumRedBits;
                    fbConfig.AccumGreenBits = pfd.CAccumGreenBits;
                    fbConfig.AccumBlueBits  = pfd.CAccumBlueBits;
                    fbConfig.AccumAlphaBits = pfd.CAccumAlphaBits;

                    if ((pfd.DwFlags & PixelFormatFlags.Stereo) != 0)
                    {
                        fbConfig.Stereo = true;
                    }

                    if ((pfd.DwFlags & PixelFormatFlags.DoubleBuffer) != 0)
                    {
                        fbConfig.Doublebuffer = true;
                    }

                    fbConfig.Handle = i + 1;
                    usableConfigs.Add(fbConfig);
                }
            }

            if (usableConfigs.Count == 0)
            {
                Engine.Log.Error("The driver doesn't seem to support OpenGL.", MessageSource.Wgl);
                return(0);
            }

            FramebufferConfig closestConfig = ChoosePixelFormat(usableConfigs);

            if (closestConfig != null)
            {
                return(closestConfig.Handle);
            }

            Engine.Log.Error("Couldn't find suitable pixel format.", MessageSource.Wgl);
            return(0);
        }