Пример #1
0
        public override void SwapBuffers()
        {
            if (_platform.DisplayMode != DisplayMode.Fullscreen)
            {
                bool dwmComposition;

                // DWM Composition is always enabled on Win8+
                if (Win32Platform.IsWindows8OrGreater)
                {
                    dwmComposition = true;
                }
                else
                {
                    HResult result = DwmApi.DwmIsCompositionEnabled(out dwmComposition);
                    if (result != HResult.S_OK)
                    {
                        dwmComposition = false;
                    }
                }

                if (dwmComposition)
                {
                    for (var i = 0; i < SwapInterval; i++)
                    {
                        DwmApi.DwmFlush();
                    }
                }
            }

            Gdi32.SwapBuffers(_dc);
        }
Пример #2
0
 public static unsafe IntPtr CreateDIBSection(IntPtr hdc, ref BitmapInfoHeader bitmapInfoHeader,
                                              DibBmiColorUsageFlag iUsage, out IntPtr ppvBits, IntPtr hSection, uint dwOffset)
 {
     fixed(BitmapInfoHeader *bitmapInfoHeaderPtr = &bitmapInfoHeader)
     {
         return(Gdi32Methods.CreateDIBSection(hdc, new IntPtr(bitmapInfoHeaderPtr), iUsage, out ppvBits, hSection,
                                              dwOffset));
     }
 }
Пример #3
0
 public static IntPtr CreateDIBSection(IntPtr hdc, ref BitmapInfo bitmapInfo,
                                       DibBmiColorUsageFlag iUsage, out IntPtr ppvBits, IntPtr hSection, uint dwOffset)
 {
     using (var pbmi = BitmapInfo.NativeAlloc(ref bitmapInfo))
     {
         return(Gdi32Methods.CreateDIBSection(hdc, pbmi.GetDangerousHandle(), iUsage, out ppvBits, hSection,
                                              dwOffset));
     }
 }
Пример #4
0
 public static IntPtr CreateDIBitmap(IntPtr hdc, ref BitmapInfoHeader
                                     lpbmih, uint fdwInit, byte[] lpbInit, ref BitmapInfo bitmapInfo,
                                     DibBmiColorUsageFlag fuUsage)
 {
     using (var pbmi = BitmapInfo.NativeAlloc(ref bitmapInfo))
     {
         return(Gdi32Methods.CreateDIBitmap(hdc, ref lpbmih, fdwInit, lpbInit, pbmi.GetDangerousHandle(),
                                            fuUsage));
     }
 }
Пример #5
0
 public static unsafe int SetDIBitsToDevice(IntPtr hdc, int xDest, int yDest, uint
                                            dwWidth, uint dwHeight, int xSrc, int ySrc, uint uStartScan, uint cScanLines,
                                            byte[] lpvBits, ref BitmapInfoHeader bitmapInfoHeader, DibBmiColorUsageFlag fuColorUse)
 {
     fixed(BitmapInfoHeader *bitmapInfoHeaderPtr = &bitmapInfoHeader)
     {
         return(Gdi32Methods.SetDIBitsToDevice(hdc, xDest, yDest,
                                               dwWidth, dwHeight, xSrc, ySrc, uStartScan, cScanLines, lpvBits, new IntPtr(bitmapInfoHeaderPtr),
                                               fuColorUse));
     }
 }
Пример #6
0
 public static int SetDIBitsToDevice(IntPtr hdc, int xDest, int yDest, uint
                                     dwWidth, uint dwHeight, int xSrc, int ySrc, uint uStartScan, uint cScanLines,
                                     byte[] lpvBits, ref BitmapInfo bitmapInfo, DibBmiColorUsageFlag fuColorUse)
 {
     using (var pbmi = BitmapInfo.NativeAlloc(ref bitmapInfo))
     {
         return(Gdi32Methods.SetDIBitsToDevice(hdc, xDest, yDest,
                                               dwWidth, dwHeight, xSrc, ySrc, uStartScan, cScanLines, lpvBits, pbmi.GetDangerousHandle(),
                                               fuColorUse));
     }
 }
Пример #7
0
        public Win32Monitor(DisplayDeviceW adapter, DisplayDeviceW?display)
        {
            Name        = display != null ? display.Value.DeviceString : adapter.DeviceString;
            AdapterName = adapter.DeviceName;
            DeviceName  = display == null ? "<<Unknown Device>>" : display.Value.DeviceName;
            Debug.Assert(Name != null);

            var dm = new DeviceMode();

            dm.dmSize = (short)Marshal.SizeOf(dm);
            User32.EnumDisplaySettingsW(adapter.DeviceName.PadRight(32, '\0'), (int)DisplaySettings.CurrentSettings, ref dm);
            Win32Platform.CheckError("Enumerating display settings.");

            Width  = dm.dmPelsWidth;
            Height = dm.dmPelsHeight;

            IntPtr dc = Gdi32.CreateDCW("DISPLAY", adapter.DeviceName, null, IntPtr.Zero);

            Debug.Assert(dc != IntPtr.Zero);

            if (Win32Platform.IsWindows81OrGreater)
            {
                WidthPhysical  = Gdi32.GetDeviceCaps(dc, DeviceCap.HorizontalSize);
                HeightPhysical = Gdi32.GetDeviceCaps(dc, DeviceCap.VertSize);
            }
            else
            {
                WidthPhysical  = (int)(dm.dmPelsWidth * 25.4f / Gdi32.GetDeviceCaps(dc, DeviceCap.LogPixelsX));
                HeightPhysical = (int)(dm.dmPelsHeight * 25.4f / Gdi32.GetDeviceCaps(dc, DeviceCap.LogPixelsY));
            }

            Gdi32.DeleteDC(dc);

            if ((adapter.StateFlags & DisplayDeviceStateFlags.ModesPruned) != 0)
            {
                ModesPruned = true;
            }

            var rect = new Rect
            {
                Left   = dm.dmPosition.X,
                Top    = dm.dmPosition.Y,
                Right  = dm.dmPosition.X + dm.dmPelsWidth,
                Bottom = dm.dmPosition.Y + dm.dmPelsHeight
            };

            User32.EnumDisplayMonitors(IntPtr.Zero, ref rect, MonitorCallback, null);
            Win32Platform.CheckError("Creating monitor.");
        }
Пример #8
0
        public static unsafe int SetRgbBitsToDevice(IntPtr hdc, int width, int height, IntPtr pixelBufferPtr,
                                                    int xSrc = 0,
                                                    int ySrc = 0, int xDest = 0, int yDest = 0, bool isRgba = true, bool isImageTopDown = true)
        {
            var bi = new BitmapInfoHeader
            {
                Size            = (uint)Marshal.SizeOf <BitmapInfoHeader>(),
                Width           = width,
                Height          = isImageTopDown ? -height : height,
                CompressionMode = BitmapCompressionMode.BI_RGB,
                BitCount        = isRgba ? (ushort)32 : (ushort)24,
                Planes          = 1
            };

            return(Gdi32Methods.SetDIBitsToDevice(hdc, xDest, yDest, (uint)width, (uint)height, xSrc, ySrc, 0,
                                                  (uint)height, pixelBufferPtr, new IntPtr(&bi),
                                                  DibBmiColorUsageFlag.DIB_RGB_COLORS));
        }
Пример #9
0
        public static void GetMonitorContentScale(IntPtr monitor, out float scaleX, out float scaleY)
        {
            uint xDpi, yDpi;

            if (Win32Platform.IsWindows81OrGreater)
            {
                ShCore.GetDpiForMonitor(monitor, MonitorDpiType.MDT_EFFECTIVE_DPI, out xDpi, out yDpi);
            }
            else
            {
                IntPtr dc = User32.GetDC(IntPtr.Zero);
                xDpi = (uint)Gdi32.GetDeviceCaps(dc, DeviceCap.LogPixelsX);
                yDpi = (uint)Gdi32.GetDeviceCaps(dc, DeviceCap.LogPixelsY);
                User32.ReleaseDC(IntPtr.Zero, dc);
            }

            scaleX = xDpi / (float)Win32Platform.DEFAULT_DPI;
            scaleY = yDpi / (float)Win32Platform.DEFAULT_DPI;
        }
Пример #10
0
        public void Init(IntPtr windowHandle, Win32Platform platform)
        {
            _platform = platform;

            // This is how you request a context version from MESA - lol
            // This needs to be pInvoked as Environment.SetEnvironmentVariable doesn't affect native getenv calls.
            _putenv_s("MESA_GL_VERSION_OVERRIDE", "3.3FC");

            // Unload old OpenGL, if any.
            IntPtr loadedOpenGl = Kernel32.GetModuleHandle("opengl32.dll");
            var    counter      = 0;

            if (loadedOpenGl != IntPtr.Zero)
            {
                Engine.Log.Info("OpenGL32.dll is already loaded. Attempting to unload...", MessageSource.WGallium);
            }
            while (loadedOpenGl != IntPtr.Zero)
            {
                Kernel32.FreeLibrary(loadedOpenGl);
                loadedOpenGl = Kernel32.GetModuleHandle("opengl32.dll");
                counter++;
                if (counter < 100)
                {
                    continue;
                }
                Engine.Log.Error("Couldn't unload the loaded OpenGL32.dll. Gallium context couldn't be created.", MessageSource.WGallium);
                return;
            }

            if (counter > 0)
            {
                Engine.Log.Info($"OpenGL32.dll was unloaded after {counter} attempts.", MessageSource.WGallium);
            }

            // Load library.
            _openGlLibrary = _platform.LoadLibrary("mesa");
            if (_openGlLibrary == IntPtr.Zero)
            {
                Engine.Log.Error("Couldn't load mesa.", MessageSource.WGallium);
                return;
            }

            var createContext = _platform.GetFunctionByName <WglFunctions.WglCreateContext>(_openGlLibrary, "wglCreateContext");

            _deleteContext   = _platform.GetFunctionByName <WglFunctions.WglDeleteContext>(_openGlLibrary, "wglDeleteContext");
            _getProcAddress  = _platform.GetFunctionByName <WglFunctions.WglGetProcAddress>(_openGlLibrary, "wglGetProcAddress");
            _makeCurrent     = _platform.GetFunctionByName <WglFunctions.WglMakeCurrent>(_openGlLibrary, "wglMakeCurrent");
            _swapIntervalExt = NativeHelpers.GetFunctionByPtr <WglFunctions.SwapInternalExt>(_getProcAddress("wglSwapIntervalEXT"));

            // Setup context.
            _dc = User32.GetDC(windowHandle);
            if (_dc == IntPtr.Zero)
            {
                Win32Platform.CheckError("WGL: Could not get window dc.", true);
            }

            int pixelFormatIdx = SupportedPixelFormat(_dc);

            if (pixelFormatIdx == 0)
            {
                return;
            }

            var pfd = new PixelFormatDescriptor();

            pfd.NSize = (ushort)Marshal.SizeOf(pfd);
            if (Gdi32.DescribePixelFormat(_dc, pixelFormatIdx, (uint)sizeof(PixelFormatDescriptor), ref pfd) == 0)
            {
                Win32Platform.CheckError("WGL: Failed to retrieve PFD for the selected pixel format.", true);
                return;
            }

            if (!Gdi32.SetPixelFormat(_dc, pixelFormatIdx, ref pfd))
            {
                Win32Platform.CheckError("WGL: Could not set pixel format.", true);
            }

            const string contextName = "Gallium-OpenGL";

            _contextHandle = createContext(_dc);
            if (_contextHandle == IntPtr.Zero)
            {
                Win32Platform.CheckError(contextName, true);
            }

            Win32Platform.CheckError("Checking if context creation passed.");
            Engine.Log.Trace($"Requested {contextName} using pixel format id {pixelFormatIdx}", MessageSource.Win32);

            Valid = true;
        }
Пример #11
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);
        }
Пример #12
0
        /// <summary>
        /// Initialize the conflict from the Windows window handle and platform reference.
        /// </summary>
        public void Init(IntPtr nativeDeviceHandle, IntPtr windowHandle, Win32Platform platform)
        {
            _platform = platform;

            // Load WGL.
            _openGlLibrary = _platform.LoadLibrary("opengl32.dll");
            if (_openGlLibrary == IntPtr.Zero)
            {
                Engine.Log.Error("opengl32.dll not found.", MessageSource.WGallium);
                return;
            }

            var createContext = _platform.GetFunctionByName <WglFunctions.WglCreateContext>(_openGlLibrary, "wglCreateContext");

            _deleteContext     = _platform.GetFunctionByName <WglFunctions.WglDeleteContext>(_openGlLibrary, "wglDeleteContext");
            _getProcAddress    = _platform.GetFunctionByName <WglFunctions.WglGetProcAddress>(_openGlLibrary, "wglGetProcAddress");
            _getCurrentDc      = _platform.GetFunctionByName <WglFunctions.WglGetCurrentDc>(_openGlLibrary, "wglGetCurrentDC");
            _getCurrentContext = _platform.GetFunctionByName <WglFunctions.WglGetCurrentContext>(_openGlLibrary, "wglGetCurrentContext");
            _makeCurrent       = _platform.GetFunctionByName <WglFunctions.WglMakeCurrent>(_openGlLibrary, "wglMakeCurrent");

            // A dummy context has to be created for opengl32.dll to load the. OpenGL ICD, from which we can then query WGL extensions.
            // This code will accept the Microsoft GDI ICD;
            Debug.Assert(nativeDeviceHandle != IntPtr.Zero);
            var pfd = new PixelFormatDescriptor();

            pfd.NSize      = (ushort)Marshal.SizeOf(pfd);
            pfd.NVersion   = 1;
            pfd.DwFlags    = PixelFormatFlags.DrawToWindow | PixelFormatFlags.SupportOpenGl | PixelFormatFlags.DoubleBuffer;
            pfd.PixelType  = (byte)PixelFormatFlags.RGBA;
            pfd.CColorBits = 24;

            if (!Gdi32.SetPixelFormat(nativeDeviceHandle, Gdi32.ChoosePixelFormat(nativeDeviceHandle, ref pfd), ref pfd))
            {
                Win32Platform.CheckError("WGL: Could not set pixel format on dummy context.", true);
            }

            // Establish dummy context.
            IntPtr rc = createContext(nativeDeviceHandle);

            if (rc == IntPtr.Zero)
            {
                Win32Platform.CheckError("WGL: Could not create dummy context.", true);
            }
            if (!_makeCurrent(nativeDeviceHandle, rc))
            {
                _deleteContext(rc);
                Win32Platform.CheckError("Could not make dummy context current.", true);
                return;
            }

            // Check supported version.
            KhronosVersion glGetString = Gl.QueryVersionExternal(GetProcAddress);

            if (glGetString != null)
            {
                if (glGetString.Major < 3)
                {
                    _deleteContext(rc);
                    Engine.Log.Error("Wgl support is lower than 3.0", MessageSource.Wgl);
                    return;
                }
            }
            else
            {
                Engine.Log.Warning("Couldn't verify context version.", MessageSource.Wgl);
            }

            Engine.Log.Trace("Loaded functions.", MessageSource.Wgl);

            // Functions must be loaded first as they're needed to retrieve the extension string that tells us whether the functions are supported
            _getExtensionsStringExt    = NativeHelpers.GetFunctionByPtr <WglFunctions.GetExtensionsStringExt>(_getProcAddress("wglGetExtensionsStringEXT"));
            _getExtensionsStringArb    = NativeHelpers.GetFunctionByPtr <WglFunctions.GetExtensionsStringArb>(_getProcAddress("wglGetExtensionsStringARB"));
            _createContextAttribs      = NativeHelpers.GetFunctionByPtr <WglFunctions.CreateContextAttribs>(_getProcAddress("wglCreateContextAttribsARB"));
            _swapIntervalExt           = NativeHelpers.GetFunctionByPtr <WglFunctions.SwapInternalExt>(_getProcAddress("wglSwapIntervalEXT"));
            _getPixelFormatAttribivArb = NativeHelpers.GetFunctionByPtr <WglFunctions.GetPixelFormatAttributes>(_getProcAddress("wglGetPixelFormatAttribivARB"));

            WglGetSupportedExtensions();
            _arbMultisample          = WglSupportedExtension("WGL_ARB_multisample");
            _arbFramebufferSRgb      = WglSupportedExtension("WGL_ARB_framebuffer_sRGB");
            _extFramebufferSRgb      = WglSupportedExtension("WGL_EXT_framebuffer_sRGB");
            _arbCreateContextProfile = WglSupportedExtension("WGL_ARB_create_context_profile");
            _arbPixelFormat          = WglSupportedExtension("WGL_ARB_pixel_format");
            _autoVSyncExtension      = WglSupportedExtension("WGL_EXT_swap_control_tear");
            bool arbCreateContext = WglSupportedExtension("WGL_ARB_create_context");

            // Dispose of dummy context.
            _deleteContext(rc);
            Engine.Log.Trace("Extensions loaded.", MessageSource.Wgl);

            // Start creating actual context.
            _dc = User32.GetDC(windowHandle);
            if (_dc == IntPtr.Zero)
            {
                Win32Platform.CheckError("WGL: Could not get window dc.", true);
            }
            int pixelFormatIdx = SupportedPixelFormat(_dc);

            if (pixelFormatIdx == 0)
            {
                return;
            }

            if (Gdi32.DescribePixelFormat(_dc, pixelFormatIdx, (uint)sizeof(PixelFormatDescriptor), ref pfd) == 0)
            {
                Win32Platform.CheckError("WGL: Failed to retrieve PFD for the selected pixel format.", true);
                return;
            }

            if (!Gdi32.SetPixelFormat(_dc, pixelFormatIdx, ref pfd))
            {
                Win32Platform.CheckError("WGL: Could not set pixel format.", true);
                return;
            }

            Engine.Log.Trace($"Context ARB: {arbCreateContext}, Profile ARB: {_arbCreateContextProfile}", MessageSource.Wgl);
            if (arbCreateContext)
            {
                // Context configurations to try.
                var contextFactory = new List <GLContextDescription>(2)
                {
                    new GLContextDescription {
                        Profile = GLProfile.Core, Debug = Engine.Configuration.GlDebugMode
                    },
                    new GLContextDescription {
                        Profile = GLProfile.Any
                    }
                };

                for (var i = 0; i < contextFactory.Count; i++)
                {
                    GLContextDescription current = contextFactory[i];

                    IntPtr handle = CreateContextArb(current);
                    if (handle == IntPtr.Zero)
                    {
                        continue;
                    }

                    _contextHandle = handle;
                    Engine.Log.Info($"Created WGL context - {current}", MessageSource.Wgl);
                    break;
                }

                // If that failed too, look for errors.
                // Fallback to legacy creation.
                if (_contextHandle == IntPtr.Zero)
                {
                    Win32Platform.CheckError("Creating WGL context");
                }
            }

            if (_contextHandle == IntPtr.Zero)
            {
                _contextHandle = createContext(_dc);
                if (_contextHandle == IntPtr.Zero)
                {
                    Win32Platform.CheckError("Creating WGL legacy context", true);
                }
                Engine.Log.Info("WGL legacy context created.", MessageSource.Wgl);
            }

            Win32Platform.CheckError("Checking if context creation passed.");
            Valid = true;
        }
Пример #13
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);
        }
Пример #14
0
 public static IntPtr CreateSolidBrush(uint r, uint g, uint b)
 {
     return(Gdi32Methods.CreateSolidBrush(Bgr32(r, g, b)));
 }
Пример #15
0
 public static IntPtr GetStockObject(StockObject fnObject)
 {
     return(Gdi32Methods.GetStockObject((int)fnObject));
 }