public static IntPtr GetProcAddress(string procName) { IntPtr result = WGL.GetProcAddress(procName); if (result == IntPtr.Zero) { NativeLibrary.TryGetExport(_opengl32Handle, procName, out result); } return(result); }
private static string GetExtensionsString() { IntPtr stringPtr; if (GetExtensionsStringARB != null) { stringPtr = GetExtensionsStringARB(WGL.GetCurrentDC()); } else { stringPtr = GetExtensionsStringEXT(); } return(Marshal.PtrToStringAnsi(stringPtr)); }
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}"); } }
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; } }
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; } }