Ejemplo n.º 1
0
        public static IntPtr GetProcAddress(string procName)
        {
            IntPtr result = WGL.GetProcAddress(procName);

            if (result == IntPtr.Zero)
            {
                NativeLibrary.TryGetExport(_opengl32Handle, procName, out result);
            }

            return(result);
        }
Ejemplo n.º 2
0
        private static string GetExtensionsString()
        {
            IntPtr stringPtr;

            if (GetExtensionsStringARB != null)
            {
                stringPtr = GetExtensionsStringARB(WGL.GetCurrentDC());
            }
            else
            {
                stringPtr = GetExtensionsStringEXT();
            }

            return(Marshal.PtrToStringAnsi(stringPtr));
        }
Ejemplo n.º 3
0
        public override void MakeCurrent(NativeWindowBase window)
        {
            if (_window != null && window != null && _window.WindowHandle.RawHandle == window.WindowHandle.RawHandle && IsCurrent)
            {
                return;
            }

            bool success;

            if (window != null)
            {
                if (!(window is WGLWindow))
                {
                    throw new InvalidOperationException($"MakeCurrent() should be used with a {typeof(WGLWindow).Name}.");
                }
                if (_deviceContext != window.DisplayHandle.RawHandle)
                {
                    throw new InvalidOperationException("MakeCurrent() should be used with a window originated from the same device context.");
                }

                success = WGL.MakeCurrent(_deviceContext, ContextHandle);
            }
            else
            {
                if (WGL.GetCurrentContext() == IntPtr.Zero)
                {
                    success = true;
                }
                else
                {
                    success = WGL.MakeCurrent(IntPtr.Zero, IntPtr.Zero);
                }
            }

            if (success)
            {
                _window = window;
            }
            else
            {
                throw new ContextException($"MakeCurrent() failed with error 0x{Marshal.GetLastWin32Error():x}");
            }
        }
Ejemplo n.º 4
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;
            }
        }
Ejemplo n.º 5
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;
            }
        }