Example #1
0
        protected override void Dispose(bool disposing)
        {
            if (!IsDisposed)
            {
                if (disposing)
                {
                    MakeCurrent(null);

                    if (_windowHandle != IntPtr.Zero)
                    {
                        Win32.Win32.DestroyWindow(_windowHandle);
                    }

                    WGL.DeleteContext(ContextHandle);
                }

                IsDisposed = true;
            }
        }
Example #2
0
        private static void EnsureInit()
        {
            if (!_isInit)
            {
                // Because WGL is terrible, we need to first create a context that will allow us to check extensions and query functions to create our contexes.

                IntPtr dummyWindow = Win32Helper.CreateNativeWindow(WindowStylesEx.WS_EX_OVERLAPPEDWINDOW,
                                                                    WindowStyles.WS_CLIPSIBLINGS | WindowStyles.WS_CLIPCHILDREN,
                                                                    "SPB intermediary context",
                                                                    0, 0, 1, 1);

                if (dummyWindow == IntPtr.Zero)
                {
                    throw new PlatformException($"CreateWindowEx failed: {Marshal.GetLastWin32Error()}");
                }

                // Enforce hidden (this is a hack around possible ShowWindow being ignored when started with a STARTUPINFO)
                ShowWindow(dummyWindow, ShowWindowFlag.SW_HIDE);

                IntPtr dummyWindowDC = GetDC(dummyWindow);

                PixelFormatDescriptor pfd = PixelFormatDescriptor.Create();

                pfd.Flags = PixelFormatDescriptorFlags.PFD_DRAW_TO_WINDOW |
                            PixelFormatDescriptorFlags.PFD_SUPPORT_OPENGL |
                            PixelFormatDescriptorFlags.PFD_DOUBLEBUFFER;
                pfd.PixelType = PixelType.PFD_TYPE_RGBA;
                pfd.ColorBits = 24;

                int res = SetPixelFormat(dummyWindowDC, ChoosePixelFormat(dummyWindowDC, ref pfd), ref pfd);

                if (res == 0)
                {
                    throw new PlatformException($"SetPixelFormat failed for dummy context: {Marshal.GetLastWin32Error()}");
                }

                IntPtr dummyContext = WGL.CreateContext(dummyWindowDC);

                if (dummyContext == IntPtr.Zero)
                {
                    throw new PlatformException($"WGL.CreateContext failed for dummy context: {Marshal.GetLastWin32Error()}");
                }

                IntPtr oldDC      = WGL.GetCurrentDC();
                IntPtr oldContext = WGL.GetCurrentContext();

                if (!WGL.MakeCurrent(dummyWindowDC, dummyContext))
                {
                    // Ensure the previous context is restored and free the new context.
                    WGL.MakeCurrent(oldDC, oldContext);
                    WGL.DeleteContext(dummyContext);

                    throw new PlatformException($"WGL.MakeCurrent failed for dummy context: {Marshal.GetLastWin32Error()}");
                }

                // Now that we have a context, query everything we need.

                IntPtr getExtensionsPtr = WGL.GetProcAddress("wglGetExtensionsStringEXT");

                if (getExtensionsPtr == IntPtr.Zero)
                {
                    getExtensionsPtr = WGL.GetProcAddress("wglGetExtensionsStringARB");
                }

                GetExtensionsString = Marshal.GetDelegateForFunctionPointer <wglGetExtensionsString>(getExtensionsPtr);

                Extensions = GetExtensionsString().Split(" ");

                // Ensure that all extensions that we are requiring are present.
                EnsureExtensionPresence("WGL_ARB_create_context");
                EnsureExtensionPresence("WGL_ARB_create_context_profile");
                EnsureExtensionPresence("WGL_ARB_pixel_format"); // TODO: do not enforce this extension as we can use legacy PFDs too.
                EnsureExtensionPresence("WGL_EXT_swap_control");

                CreateContextAttribsArb   = Marshal.GetDelegateForFunctionPointer <wglCreateContextAttribsARBDelegate>(WGL.GetProcAddress("wglCreateContextAttribsARB"));
                ChoosePixelFormatArb      = Marshal.GetDelegateForFunctionPointer <wglChoosePixelFormatARBDelegate>(WGL.GetProcAddress("wglChoosePixelFormatARB"));
                GetPixelFormatAttribivARB = Marshal.GetDelegateForFunctionPointer <wglGetPixelFormatAttribivARB>(WGL.GetProcAddress("wglGetPixelFormatAttribivARB"));
                SwapInterval    = Marshal.GetDelegateForFunctionPointer <wglSwapIntervalEXTDelegate>(WGL.GetProcAddress("wglSwapIntervalEXT"));
                GetSwapInterval = Marshal.GetDelegateForFunctionPointer <wglGetSwapIntervalEXTDelegate>(WGL.GetProcAddress("wglGetSwapIntervalEXT"));


                // We got everything we needed, clean up!
                WGL.MakeCurrent(oldDC, oldContext);
                WGL.DeleteContext(dummyContext);
                DestroyWindow(dummyWindow);

                _opengl32Handle = NativeLibrary.Load("opengl32.dll");

                _isInit = true;
            }
        }