static Wgl() { // save the current GL context var prevDC = Wgl.wglGetCurrentDC(); var prevGLRC = Wgl.wglGetCurrentContext(); // register the dummy window class var wc = new WNDCLASS { style = (User32.CS_HREDRAW | User32.CS_VREDRAW | User32.CS_OWNDC), lpfnWndProc = (WNDPROC)User32.DefWindowProc, cbClsExtra = 0, cbWndExtra = 0, hInstance = Kernel32.CurrentModuleHandle, hCursor = User32.LoadCursor(IntPtr.Zero, (int)User32.IDC_ARROW), hIcon = User32.LoadIcon(IntPtr.Zero, (IntPtr)User32.IDI_WINLOGO), hbrBackground = IntPtr.Zero, lpszMenuName = null, lpszClassName = "DummyClass" }; if (User32.RegisterClass(ref wc) == 0) { throw new Exception("Could not register dummy class."); } // get the the dummy window bounds var windowRect = new RECT { left = 0, right = 8, top = 0, bottom = 8 }; User32.AdjustWindowRectEx(ref windowRect, WindowStyles.WS_SYSMENU, false, User32.WS_EX_CLIENTEDGE); // create the dummy window var dummyWND = User32.CreateWindowEx( User32.WS_EX_CLIENTEDGE, "DummyClass", "DummyWindow", WindowStyles.WS_CLIPSIBLINGS | WindowStyles.WS_CLIPCHILDREN | WindowStyles.WS_SYSMENU, 0, 0, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, IntPtr.Zero, IntPtr.Zero, Kernel32.CurrentModuleHandle, IntPtr.Zero); if (dummyWND == IntPtr.Zero) { User32.UnregisterClass("DummyClass", Kernel32.CurrentModuleHandle); throw new Exception("Could not create dummy window."); } // get the dummy DC var dummyDC = User32.GetDC(dummyWND); // get the dummy pixel format var dummyPFD = new PIXELFORMATDESCRIPTOR(); dummyPFD.nSize = (ushort)Marshal.SizeOf(dummyPFD); dummyPFD.nVersion = 1; dummyPFD.dwFlags = Gdi32.PFD_DRAW_TO_WINDOW | Gdi32.PFD_SUPPORT_OPENGL; dummyPFD.iPixelType = Gdi32.PFD_TYPE_RGBA; dummyPFD.cColorBits = 32; dummyPFD.cDepthBits = 24; dummyPFD.cStencilBits = 8; dummyPFD.iLayerType = Gdi32.PFD_MAIN_PLANE; var dummyFormat = Gdi32.ChoosePixelFormat(dummyDC, ref dummyPFD); Gdi32.SetPixelFormat(dummyDC, dummyFormat, ref dummyPFD); // get the dummy GL context var dummyGLRC = Wgl.wglCreateContext(dummyDC); if (dummyGLRC == IntPtr.Zero) { throw new Exception("Could not create dummy GL context."); } Wgl.wglMakeCurrent(dummyDC, dummyGLRC); VersionString = Wgl.GetString(Wgl.GL_VERSION); // get the extension methods using the dummy context wglGetExtensionsStringARB = Wgl.wglGetProcAddress <wglGetExtensionsStringARBDelegate>("wglGetExtensionsStringARB"); wglChoosePixelFormatARB = Wgl.wglGetProcAddress <wglChoosePixelFormatARBDelegate>("wglChoosePixelFormatARB"); wglCreatePbufferARB = Wgl.wglGetProcAddress <wglCreatePbufferARBDelegate>("wglCreatePbufferARB"); wglDestroyPbufferARB = Wgl.wglGetProcAddress <wglDestroyPbufferARBDelegate>("wglDestroyPbufferARB"); wglGetPbufferDCARB = Wgl.wglGetProcAddress <wglGetPbufferDCARBDelegate>("wglGetPbufferDCARB"); wglReleasePbufferDCARB = Wgl.wglGetProcAddress <wglReleasePbufferDCARBDelegate>("wglReleasePbufferDCARB"); wglSwapIntervalEXT = Wgl.wglGetProcAddress <wglSwapIntervalEXTDelegate>("wglSwapIntervalEXT"); // destroy the dummy GL context Wgl.wglMakeCurrent(dummyDC, IntPtr.Zero); Wgl.wglDeleteContext(dummyGLRC); // destroy the dummy window User32.DestroyWindow(dummyWND); User32.UnregisterClass("DummyClass", Kernel32.CurrentModuleHandle); // reset the initial GL context Wgl.wglMakeCurrent(prevDC, prevGLRC); }