unsafe void InitPixelFormat(IntPtr hdc) { // pfd Tells Windows How We Want Things To Be var pfd = new PixelformatDescriptor { nSize = (ushort)Marshal.SizeOf <PixelformatDescriptor> (), // size of this pfd nVersion = 1, // version number dwFlags = PFD_FLAGS.DRAW_TO_WINDOW | PFD_FLAGS.SUPPORT_OPENGL | PFD_FLAGS.DOUBLEBUFFER, // support window, OpenGL, double buffered iPixelType = PFD_PIXEL_TYPE.RGBA, // RGBA type cColorBits = 24, // 24-bit color depth cRedBits = 0, cRedShift = 0, cGreenBits = 0, cGreenShift = 0, cBlueBits = 0, cBlueShift = 0, // color bits ignored cAlphaBits = 0, // no alpha buffer cAlphaShift = 0, // shift bit ignored cAccumBits = 0, // no accumulation buffer cAccumRedBits = 0, cAccumGreenBits = 0, cAccumBlueBits = 0, cAccumAlphaBits = 0, // accum bits ignored cDepthBits = 32, // 16-bit z-buffer cStencilBits = 0, // no stencil buffer cAuxBuffers = 0, // no auxiliary buffer iLayerType = PFD_LAYER_TYPES.MAIN_PLANE, // main layer bReserved = 0, // reserved dwLayerMask = 0, dwVisibleMask = 0, dwDamageMask = 0 // layer masks ignored }; int iPixelFormat = wgl.ChoosePixelFormat(hdc, (IntPtr)(&pfd)); // get the device context's best, available pixel format match if (iPixelFormat == 0) { //MessageBox::Show ( "ChoosePixelFormat Failed" ); return; } if (wgl.SetPixelFormat(hdc, iPixelFormat, (IntPtr)(&pfd)) == false) { //MessageBox::Show ( "SetPixelFormat Failed" ); return; } renderContext = wgl.CreateContext(hdc); if (renderContext == IntPtr.Zero) { //MessageBox::Show ( "wglCreateContext Failed" ); return; } if ((wgl.MakeCurrent(hdc, renderContext)) == false) { //MessageBox::Show ( "wglMakeCurrent Failed" ); return; } }
private void CreateOpenGLContext(IntPtr hwnd) { this.hwnd = hwnd; this.hDC = GetDC(hwnd); var pixelformatdescriptor = new PIXELFORMATDESCRIPTOR(); pixelformatdescriptor.Init(); #if !USE_MSAA int pixelFormat; pixelFormat = ChoosePixelFormat(this.hDC, ref pixelformatdescriptor); SetPixelFormat(this.hDC, pixelFormat, ref pixelformatdescriptor); this.hglrc = wglCreateContext(this.hDC); wglMakeCurrent(this.hDC, this.hglrc); #else IntPtr tempContext = IntPtr.Zero; IntPtr tempHwnd = IntPtr.Zero; //Create temporary window IntPtr hInstance = Process.GetCurrentProcess().SafeHandle.DangerousGetHandle(); WNDCLASS wndclass = new WNDCLASS() { style = 0x0002 /*CS_HREDRAW*/ | 0x0001 /*CS_VREDRAW*/ | 0x0020 /*CS_OWNDC*/, lpfnWndProc = (hWnd, msg, wParam, lParam) => DefWindowProc(hWnd, msg, wParam, lParam), hInstance = hInstance, lpszClassName = "tmpWindowForMSAA~" + this.GetHashCode() }; ushort atom = RegisterClassW(ref wndclass); if (atom == 0) { throw new WindowCreateException(string.Format("RegisterClass error: {0}", Marshal.GetLastWin32Error())); } tempHwnd = CreateWindowEx( 0, new IntPtr(atom), "tmpWindow~", (uint)(WindowStyles.WS_CLIPSIBLINGS | WindowStyles.WS_CLIPCHILDREN), 0, 0, 1, 1, hwnd, IntPtr.Zero, hInstance, IntPtr.Zero); if (tempHwnd == IntPtr.Zero) { throw new WindowCreateException(string.Format("CreateWindowEx for tempContext error: {0}", Marshal.GetLastWin32Error())); } IntPtr tempHdc = GetDC(tempHwnd); var tempPixelFormat = ChoosePixelFormat(tempHdc, ref pixelformatdescriptor); if (tempPixelFormat == 0) { throw new Exception(string.Format("ChoosePixelFormat failed: error {0}", Marshal.GetLastWin32Error())); } if (!SetPixelFormat(tempHdc, tempPixelFormat, ref pixelformatdescriptor)) { throw new Exception(string.Format("SetPixelFormat failed: error {0}", Marshal.GetLastWin32Error())); } tempContext = Wgl.CreateContext(tempHdc);//Crate temp context to load entry points if (tempContext == IntPtr.Zero) { throw new Exception(string.Format("wglCreateContext for tempHdc failed: error {0}", Marshal.GetLastWin32Error())); } if (!Wgl.MakeCurrent(tempHdc, tempContext)) { throw new Exception(string.Format("wglMakeCurrent for tempContext failed: error {0}", Marshal.GetLastWin32Error())); } //load wgl entry points for wglChoosePixelFormatARB new Wgl().LoadEntryPoints(tempHdc); int[] iPixAttribs = { (int)WGL.WGL_SUPPORT_OPENGL_ARB, (int)GL.GL_TRUE, (int)WGL.WGL_DRAW_TO_WINDOW_ARB, (int)GL.GL_TRUE, (int)WGL.WGL_DOUBLE_BUFFER_ARB, (int)GL.GL_TRUE, (int)WGL.WGL_PIXEL_TYPE_ARB, (int)WGL.WGL_TYPE_RGBA_ARB, (int)WGL.WGL_ACCELERATION_ARB, (int)WGL.WGL_FULL_ACCELERATION_ARB, (int)WGL.WGL_COLOR_BITS_ARB, 32, (int)WGL.WGL_DEPTH_BITS_ARB, 24, (int)WGL.WGL_STENCIL_BITS_ARB, 8, (int)WGL.WGL_SWAP_METHOD_ARB, (int)WGL.WGL_SWAP_EXCHANGE_ARB, (int)WGL.WGL_SAMPLE_BUFFERS_ARB, (int)GL.GL_TRUE,//Enable MSAA (int)WGL.WGL_SAMPLES_ARB, 16, 0 }; int pixelFormat; uint numFormats; var result = Wgl.ChoosePixelFormatARB(this.hDC, iPixAttribs, null, 1, out pixelFormat, out numFormats); if (result == false || numFormats == 0) { throw new Exception(string.Format("wglChoosePixelFormatARB failed: error {0}", Marshal.GetLastWin32Error())); } if (!DescribePixelFormat(this.hDC, pixelFormat, (uint)Marshal.SizeOf <PIXELFORMATDESCRIPTOR>(), ref pixelformatdescriptor)) { throw new Exception(string.Format("DescribePixelFormat failed: error {0}", Marshal.GetLastWin32Error())); } if (!SetPixelFormat(this.hDC, pixelFormat, ref pixelformatdescriptor)) { throw new Exception(string.Format("SetPixelFormat failed: error {0}", Marshal.GetLastWin32Error())); } if ((this.hglrc = wglCreateContext(this.hDC)) == IntPtr.Zero) { throw new Exception(string.Format("wglCreateContext failed: error {0}", Marshal.GetLastWin32Error())); } Wgl.MakeCurrent(IntPtr.Zero, IntPtr.Zero); Wgl.DeleteContext(tempContext); ReleaseDC(tempHwnd, tempHdc); DestroyWindow(tempHwnd); if (!wglMakeCurrent(this.hDC, this.hglrc)) { throw new Exception(string.Format("wglMakeCurrent failed: error {0}", Marshal.GetLastWin32Error())); } Utility.CheckGLError(); #endif GL.GetIntegerv(GL.GL_STENCIL_BITS, IntBuffer); var stencilBits = IntBuffer[0]; if (stencilBits != 8) { throw new Exception("Failed to set stencilBits to 9."); } PrintGraphicInfo(); }
/// <summary> /// Initialize WGL functions /// </summary> /// <param name="mainWindowHwnd"></param> /// <remarks> /// //refer to /// https://github.com/glfw/glfw/blob/3327050ca66ad34426a82c217c2d60ced61526b7/src/wgl_context.c#L408 /// </remarks> internal static void Init(IntPtr mainWindowHwnd) { if (EntryPoints != null)//already initialized { return; } IntPtr tempContext = IntPtr.Zero; IntPtr tempHwnd = IntPtr.Zero; //Create temporary window IntPtr hInstance = Process.GetCurrentProcess().SafeHandle.DangerousGetHandle(); WNDCLASS wndclass = new WNDCLASS() { style = 0x0002 /*CS_HREDRAW*/ | 0x0001 /*CS_VREDRAW*/ | 0x0020 /*CS_OWNDC*/, lpfnWndProc = (hWnd, msg, wParam, lParam) => DefWindowProc(hWnd, msg, wParam, lParam), hInstance = hInstance, lpszClassName = "tmpWindowForMSAA~" + tempHwnd.GetHashCode() }; ushort atom = RegisterClassW(ref wndclass); if (atom == 0) { throw new WindowCreateException(string.Format("RegisterClass error: {0}", Marshal.GetLastWin32Error())); } //TODO wgl entry point only need to be loaded once! tempHwnd = CreateWindowEx( 0, new IntPtr(atom), "tmpWindow~", (uint)(WindowStyles.WS_CLIPSIBLINGS | WindowStyles.WS_CLIPCHILDREN), 0, 0, 1, 1, mainWindowHwnd, IntPtr.Zero, hInstance, IntPtr.Zero); if (tempHwnd == IntPtr.Zero) { throw new WindowCreateException(string.Format("CreateWindowEx for tempContext error: {0}", Marshal.GetLastWin32Error())); } IntPtr tempHdc = GetDC(tempHwnd); var pixelformatdescriptor = new PIXELFORMATDESCRIPTOR(); pixelformatdescriptor.Init(); var tempPixelFormat = ChoosePixelFormat(tempHdc, ref pixelformatdescriptor); if (tempPixelFormat == 0) { throw new Exception(string.Format("ChoosePixelFormat failed: error {0}", Marshal.GetLastWin32Error())); } if (!SetPixelFormat(tempHdc, tempPixelFormat, ref pixelformatdescriptor)) { throw new Exception(string.Format("SetPixelFormat failed: error {0}", Marshal.GetLastWin32Error())); } tempContext = Wgl.CreateContext(tempHdc);//Crate temp context to load entry points if (tempContext == IntPtr.Zero) { throw new Exception(string.Format("wglCreateContext for tempHdc failed: error {0}", Marshal.GetLastWin32Error())); } if (!Wgl.MakeCurrent(tempHdc, tempContext)) { throw new Exception(string.Format("wglMakeCurrent for tempContext failed: error {0}", Marshal.GetLastWin32Error())); } //load wgl entry points for wglChoosePixelFormatARB new Wgl().LoadEntryPoints(tempHdc); Wgl.MakeCurrent(IntPtr.Zero, IntPtr.Zero); Wgl.DeleteContext(tempContext); ReleaseDC(tempHwnd, tempHdc); DestroyWindow(tempHwnd); }