/// <summary> /// /// </summary> /// <param name="wnd"></param> /// <exception cref="AccessViolationException">OpenGL subsystem encountered an access violation, try updating graphics drivers</exception> /// <exception cref="InvalidOperationException">Unable to create OpenGL context</exception> /// <exception cref="NotSupportedException">OpenGL 3.2 is not supported by this system</exception> /// <example> /// public class DisplayForm : Form /// { /// private WglContext ctx; /// protected override virtual void OnHandleCreated(EventArgs e) /// { /// ctx = new WglContext(); /// ctx.CreateContext(this.Handle); /// } /// protected override virtual void OnClosing(ClosingEventArgs e) /// { /// ctx.Dispose(); /// } /// } /// </example> public override void CreateContext(IntPtr wnd, IntPtr draw, OpenGLContext share) { // Force OpenGL library to link // or we will not be able to create a context linker = GetLinker(); hwnd = wnd; display = hwnd; int pixel_format = 0; bool valid = false; PIXELFORMATDESCRIPTOR desc = new PIXELFORMATDESCRIPTOR(); if (draw == IntPtr.Zero) { drawable = GetDC(wnd); } else { drawable = draw; } desc.nSize = (short)Marshal.SizeOf(desc); desc.nVersion = 1; desc.dwFlags = PixelFormatFlags.PFD_DOUBLEBUFFER | PixelFormatFlags.PFD_DRAW_TO_WINDOW | PixelFormatFlags.PFD_SUPPORT_OPENGL; desc.cDepthBits = 32; desc.cColorBits = 32; pixel_format = ChoosePixelFormat(drawable, ref desc); SetPixelFormat(drawable, pixel_format, ref desc); // Create legacy OpenGL context handle = wglCreateContext(drawable); wglMakeCurrent(drawable, handle); wglGetExtensionStringARB = GetProc <GetExtensionsStringARB>("wglGetExtensionStringARB"); wglChoosePixelFormatARB = GetProc <ChoosePixelFormatARB>("wglChoosePixelFormatARB"); wglGetPixelFormatAttribfvARB = GetProc <GetPixelFormatAttribfvARB>("wglGetPixelFormatAttribfvARB"); wglGetPixelFormatAttribivARB = GetProc <GetPixelFormatAttribivARB>("wglGetPixelFormatAttribivARB"); string ext = ""; if (wglGetExtensionStringARB != null) { ext = Marshal.PtrToStringAnsi(wglGetExtensionStringARB(drawable)); } var extensions = ext.Split(' '); if (drawable != IntPtr.Zero && wglChoosePixelFormatARB != null) { var fAttributes = new float[] { 0, 0 }; var iAttributes = new int[] { WGL_DRAW_TO_WINDOW_ARB, 1, WGL_SUPPORT_OPENGL_ARB, 1, WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB, WGL_COLOR_BITS_ARB, 24, WGL_ALPHA_BITS_ARB, 8, WGL_DEPTH_BITS_ARB, 24, WGL_STENCIL_BITS_ARB, 8, WGL_DOUBLE_BUFFER_ARB, 1, WGL_SAMPLE_BUFFERS_ARB, 1, WGL_SAMPLES_ARB, samples, // Check For 4x Multisampling 0, 0 }; uint num_formats = 0; valid = wglChoosePixelFormatARB(drawable, iAttributes, fAttributes, 1, ref pixel_format, ref num_formats) && num_formats > 0; if (valid) { wglMakeCurrent(IntPtr.Zero, IntPtr.Zero); wglDeleteContext(handle); SetPixelFormat(drawable, pixel_format, ref desc); handle = wglCreateContext(drawable); wglMakeCurrent(drawable, handle); } } wglCreateContextAttribsARB = GetProc <CreateContextAttribsARB>("wglCreateContextAttribsARB"); var s = OpenGL.glGetString((uint)OpenGL.Const.GL_VERSION); var str = Marshal.PtrToStringAnsi(s); var sub = str.Split('.'); int major = 0; int minor = 0; int revision = 0; int.TryParse(sub[0], out major); int.TryParse(sub[1], out minor); if (sub.Length >= 3) { int.TryParse(sub[0], out revision); } Glorg2.Debugging.Debug.WriteLine("OpenGL version " + major + "." + minor + " supported by your system."); if (major < 3) { throw new NotSupportedException("OpenGL 3 is not supported."); } if (minor < 2 && major == 3) { System.Diagnostics.Debug.WriteLine("OpenGL 3.2 is not supported. Consider upgrading display drivers."); } if (wglCreateContextAttribsARB != null) { int[] attribs = new int[] { WGL_CONTEXT_MAJOR_VERSION_ARB, major, WGL_CONTEXT_MINOR_VERSION_ARB, minor, WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0 }; IntPtr share_ctx = IntPtr.Zero; if (share != null) { share_ctx = share.Handle; } IntPtr newhandle = wglCreateContextAttribsARB(drawable, share_ctx, attribs); if (newhandle != IntPtr.Zero) { wglMakeCurrent(IntPtr.Zero, IntPtr.Zero); var err = OpenGL.glGetError(); wglDeleteContext(handle); handle = IntPtr.Zero; if (newhandle != IntPtr.Zero) // If OpenGL 3.0 context creation failed, fallback to legacy 2.x { handle = newhandle; } else { throw new NotSupportedException("Could not initialize OpenGL " + major + "." + minor + " : " + err.ToString()); } } else if (share_ctx != IntPtr.Zero) { wglShareLists(handle, share_ctx); } } else { throw new NotSupportedException("OpenGL 3.2 is not supported by your system."); } if (handle != IntPtr.Zero) { wglMakeCurrent(drawable, handle); } else { throw new NotSupportedException("Could not create OpenGL context"); } }