private void LoadExtensions() { WglChoosePixelFormatARB = Loader.Get <wglChoosePixelFormatARB>(); WglGetPixelFormatAttribivARB = Loader.Get <wglGetPixelFormatAttribivARB>(); WglSwapIntervalEXT = Loader.Get <wglSwapIntervalEXT>(); WglCreateContextAttribsARB = Loader.Get <wglCreateContextAttribsARB>(); }
private void LoadExtensions() { WglChoosePixelFormatARB = Loader.Get<wglChoosePixelFormatARB>(); WglGetPixelFormatAttribivARB = Loader.Get<wglGetPixelFormatAttribivARB>(); WglSwapIntervalEXT = Loader.Get<wglSwapIntervalEXT>(); WglCreateContextAttribsARB = Loader.Get<wglCreateContextAttribsARB>(); }
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; } }