/// <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); }
/// <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); }
/// <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); }