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); }
public WglContext() { var wc = new WNDCLASS { cbClsExtra = 0, cbWndExtra = 0, hbrBackground = IntPtr.Zero, hCursor = User32.LoadCursor(IntPtr.Zero, (int)User32.IDC_ARROW), hIcon = User32.LoadIcon(IntPtr.Zero, (IntPtr)User32.IDI_APPLICATION), hInstance = Kernel32.CurrentModuleHandle, lpfnWndProc = (WNDPROC)User32.DefWindowProc, lpszClassName = "Griffin", lpszMenuName = null, style = User32.CS_HREDRAW | User32.CS_VREDRAW | User32.CS_OWNDC }; gWC = User32.RegisterClass(ref wc); if (gWC == 0) { throw new Exception("Could not register window class."); } fWindow = User32.CreateWindow( "Griffin", "The Invisible Man", WindowStyles.WS_OVERLAPPEDWINDOW, 0, 0, 1, 1, IntPtr.Zero, IntPtr.Zero, Kernel32.CurrentModuleHandle, IntPtr.Zero); if (fWindow == IntPtr.Zero) { throw new Exception($"Could not create window."); } fDeviceContext = User32.GetDC(fWindow); if (fDeviceContext == IntPtr.Zero) { Destroy(); throw new Exception("Could not get device context."); } if (!Wgl.HasExtension(fDeviceContext, "WGL_ARB_pixel_format") || !Wgl.HasExtension(fDeviceContext, "WGL_ARB_pbuffer")) { Destroy(); throw new Exception("DC does not have extensions."); } var iAttrs = new int[] { Wgl.WGL_ACCELERATION_ARB, Wgl.WGL_FULL_ACCELERATION_ARB, Wgl.WGL_DRAW_TO_WINDOW_ARB, Wgl.TRUE, //Wgl.WGL_DOUBLE_BUFFER_ARB, (doubleBuffered ? TRUE : FALSE), Wgl.WGL_SUPPORT_OPENGL_ARB, Wgl.TRUE, Wgl.WGL_RED_BITS_ARB, 8, Wgl.WGL_GREEN_BITS_ARB, 8, Wgl.WGL_BLUE_BITS_ARB, 8, Wgl.WGL_ALPHA_BITS_ARB, 8, Wgl.WGL_STENCIL_BITS_ARB, 8, Wgl.NONE, Wgl.NONE }; var piFormats = new int[1]; uint nFormats; Wgl.wglChoosePixelFormatARB(fDeviceContext, iAttrs, null, (uint)piFormats.Length, piFormats, out nFormats); if (nFormats == 0) { Destroy(); throw new Exception("Could not get pixel formats."); } fPbuffer = Wgl.wglCreatePbufferARB(fDeviceContext, piFormats[0], 1, 1, null); if (fPbuffer == IntPtr.Zero) { Destroy(); throw new Exception("Could not create Pbuffer."); } fPbufferDC = Wgl.wglGetPbufferDCARB(fPbuffer); if (fPbufferDC == IntPtr.Zero) { Destroy(); throw new Exception("Could not get Pbuffer DC."); } var prevDC = Wgl.wglGetCurrentDC(); var prevGLRC = Wgl.wglGetCurrentContext(); fPbufferGlContext = Wgl.wglCreateContext(fPbufferDC); Wgl.wglMakeCurrent(prevDC, prevGLRC); if (fPbufferGlContext == IntPtr.Zero) { Destroy(); throw new Exception("Could not creeate Pbuffer GL context."); } }
public override void DestroyTexture(uint texture) { Wgl.glDeleteTextures(1, new[] { texture }); }
public WglContext() { if (!Wgl.HasExtension(window.DeviceContextHandle, "WGL_ARB_pixel_format") || !Wgl.HasExtension(window.DeviceContextHandle, "WGL_ARB_pbuffer")) { throw new Exception("DC does not have extensions."); } var iAttrs = new int[] { Wgl.WGL_ACCELERATION_ARB, Wgl.WGL_FULL_ACCELERATION_ARB, Wgl.WGL_DRAW_TO_WINDOW_ARB, Wgl.TRUE, //Wgl.WGL_DOUBLE_BUFFER_ARB, (doubleBuffered ? TRUE : FALSE), Wgl.WGL_SUPPORT_OPENGL_ARB, Wgl.TRUE, Wgl.WGL_RED_BITS_ARB, 8, Wgl.WGL_GREEN_BITS_ARB, 8, Wgl.WGL_BLUE_BITS_ARB, 8, Wgl.WGL_ALPHA_BITS_ARB, 8, Wgl.WGL_STENCIL_BITS_ARB, 8, Wgl.NONE, Wgl.NONE }; var piFormats = new int[1]; uint nFormats; lock (fLock) { // HACK: This call seems to cause deadlocks on some systems. Wgl.wglChoosePixelFormatARB(window.DeviceContextHandle, iAttrs, null, (uint)piFormats.Length, piFormats, out nFormats); } if (nFormats == 0) { Destroy(); throw new Exception("Could not get pixel formats."); } pbufferHandle = Wgl.wglCreatePbufferARB(window.DeviceContextHandle, piFormats[0], 1, 1, null); if (pbufferHandle == IntPtr.Zero) { Destroy(); throw new Exception("Could not create Pbuffer."); } pbufferDeviceContextHandle = Wgl.wglGetPbufferDCARB(pbufferHandle); if (pbufferDeviceContextHandle == IntPtr.Zero) { Destroy(); throw new Exception("Could not get Pbuffer DC."); } var prevDC = Wgl.wglGetCurrentDC(); var prevGLRC = Wgl.wglGetCurrentContext(); pbufferGlContextHandle = Wgl.wglCreateContext(pbufferDeviceContextHandle); Wgl.wglMakeCurrent(prevDC, prevGLRC); if (pbufferGlContextHandle == IntPtr.Zero) { Destroy(); throw new Exception("Could not creeate Pbuffer GL context."); } }