/// <summary> /// Create a new context and setup all necessary information /// </summary> /// <param name="handle">Window handle which represents the destination in the window subsystem such as X or Windows.</param> public abstract void CreateContext(IntPtr handle, IntPtr drawable, OpenGLContext share);
/// <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"); } }
public override void CreateContext(IntPtr wnd_handle, IntPtr drawable, OpenGLContext share) { // Force loading of OpenGL library // This is later used by the OpenGL class to implement extensions. //linker = GetLinker(); display = API.OpenDisplay(IntPtr.Zero); if (display == IntPtr.Zero) { throw new InvalidOperationException("Cannot connect to X server"); } wnd = wnd_handle; int[] attr = { Glx.GLX_X_RENDERABLE, 1, Glx.GLX_DRAWABLE_TYPE, Glx.GLX_WINDOW_BIT, Glx.GLX_RENDER_TYPE, Glx.GLX_RGBA_BIT, Glx.GLX_X_VISUAL_TYPE, Glx.GLX_TRUE_COLOR, Glx.GLX_RED_SIZE, 8, Glx.GLX_GREEN_SIZE, 8, Glx.GLX_BLUE_SIZE, 8, Glx.GLX_ALPHA_SIZE, 0, Glx.GLX_DEPTH_SIZE, 16, //Glx.GLX_STENCIL_SIZE , 8, Glx.GLX_DOUBLEBUFFER, 1, 0, 0 }; API.MapWindow(display, wnd); int def_screen = API.DefaultScreen(display); Console.WriteLine("Display: 0x" + display.ToString("x")); Console.WriteLine("Deault screen: 0x" + def_screen.ToString("x")); int[] elems = new int[] { 0 }; //IntPtr fb = Glx.glXChooseFBConfig(display, def_screen, attr, elems); //if (fb == IntPtr.Zero) //throw new InvalidOperationException("Could not retrieve framebuffer configuration"); Console.WriteLine(elems[0]); //var info_ptr = Glx.glXGetVisualFromFBConfig(display, Marshal.ReadIntPtr(fb)); attr = new int[] { GLX_RGBA, GLX_DEPTH_SIZE, 32, GLX_DOUBLEBUFFER, 0 }; //IntPtr info_ptr = Glx.glXChooseVisual(display, def_screen, attr); var info_ptr = API.DefaultVisual(display, def_screen); if (info_ptr == IntPtr.Zero) { throw new NotSupportedException("OpenGL is not supported."); } VisualInfo info = new VisualInfo(); Marshal.PtrToStructure(info_ptr, info); visual = info_ptr; handle = Glx.glXCreateContext(display, visual, IntPtr.Zero, true); if (handle == IntPtr.Zero) { throw new InvalidOperationException("Unable to create OpenGL context"); } Glx.glXMakeCurrent(display, visual, handle); int[] parameters = new int[] { GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 2, 0 }; glXCreateContextAttribsARB = GetProc <XCreateContextAttribsARBProc>("glXCreateContextAttribsARB"); if (glXCreateContextAttribsARB == null) { throw new NotSupportedException("OpenGL 3.0 not supported."); } IntPtr new_handle = glXCreateContextAttribsARB(display, info_ptr, share.Handle, true, parameters); if (new_handle == IntPtr.Zero) { throw new NotSupportedException("OpenGL 3.0 not supported."); } Glx.glXMakeCurrent(display, visual, IntPtr.Zero); Glx.glXDestroyContext(display, handle); Glx.glXMakeCurrent(display, visual, new_handle); handle = new_handle; Console.WriteLine("glX Initialization succeded."); }