Example #1
0
        /// <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");
            }
        }