/// <summary> /// Create the GlControl context. /// </summary> protected virtual void CreateContext() { if (_RenderContext != IntPtr.Zero) { throw new InvalidOperationException("context already created"); } KhronosVersion currentVersion = Gl.CurrentVersion; Gl.Extensions currentExtensions = Gl.CurrentExtensions; bool hasCreateContext = true; bool hasCreateContextProfile = true; bool hasCreateContextRobustness = true; hasCreateContextProfile &= currentVersion.Api == KhronosVersion.ApiGl && currentVersion >= Gl.Version_300; switch (Environment.OSVersion.Platform) { case PlatformID.Win32NT: Wgl.Extensions currentWglExtensions = Wgl.CurrentExtensions; hasCreateContext &= currentWglExtensions.CreateContext_ARB || currentWglExtensions.CreateContextProfile_ARB; hasCreateContextProfile &= currentWglExtensions.CreateContextProfile_ARB; hasCreateContextRobustness = currentWglExtensions.CreateContextRobustness_ARB; break; case PlatformID.Unix: Glx.Extensions currentGlxExtensions = Glx.CurrentExtensions; hasCreateContext &= currentGlxExtensions.CreateContext_ARB; hasCreateContextProfile &= currentGlxExtensions.CreateContextProfile_ARB; hasCreateContextRobustness = currentGlxExtensions.CreateContextRobustness_ARB; break; } if (hasCreateContext) { List <int> attributes = new List <int>(); uint contextProfile = 0, contextFlags = 0; bool debuggerAttached = Debugger.IsAttached; #region WGL_ARB_create_context|GLX_ARB_create_context // The default values for WGL_CONTEXT_MAJOR_VERSION_ARB and WGL_CONTEXT_MINOR_VERSION_ARB are 1 and 0 respectively. In this // case, implementations will typically return the most recent version of OpenGL they support which is backwards compatible with OpenGL 1.0 // (e.g. 3.0, 3.1 + GL_ARB_compatibility, or 3.2 compatibility profile) [from WGL_ARB_create_context spec] Debug.Assert(Wgl.CONTEXT_MAJOR_VERSION_ARB == Glx.CONTEXT_MAJOR_VERSION_ARB); Debug.Assert(Wgl.CONTEXT_MINOR_VERSION_ARB == Glx.CONTEXT_MINOR_VERSION_ARB); if (Version != null) { attributes.AddRange(new int[] { Wgl.CONTEXT_MAJOR_VERSION_ARB, Version.Major, Wgl.CONTEXT_MINOR_VERSION_ARB, Version.Minor }); } else { attributes.AddRange(new int[] { Wgl.CONTEXT_MAJOR_VERSION_ARB, currentVersion.Major, Wgl.CONTEXT_MINOR_VERSION_ARB, currentVersion.Minor }); } if ((_DebugContextBit == AttributePermission.Enabled) || (debuggerAttached && _DebugContextBit == AttributePermission.EnabledInDebugger)) { Debug.Assert(Wgl.CONTEXT_DEBUG_BIT_ARB == Glx.CONTEXT_DEBUG_BIT_ARB); contextFlags |= Wgl.CONTEXT_DEBUG_BIT_ARB; } if ((_ForwardCompatibleContextBit == AttributePermission.Enabled) || (debuggerAttached && _ForwardCompatibleContextBit == AttributePermission.EnabledInDebugger)) { Debug.Assert(Wgl.CONTEXT_FORWARD_COMPATIBLE_BIT_ARB == Glx.CONTEXT_FORWARD_COMPATIBLE_BIT_ARB); contextFlags |= Wgl.CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; } #endregion #region WGL_ARB_create_context_profile|GLX_ARB_create_context_profile if (hasCreateContextProfile) { switch (_ProfileType) { case ProfileType.Core: Debug.Assert(Wgl.CONTEXT_CORE_PROFILE_BIT_ARB == Glx.CONTEXT_CORE_PROFILE_BIT_ARB); contextProfile |= Wgl.CONTEXT_CORE_PROFILE_BIT_ARB; break; case ProfileType.Compatibility: Debug.Assert(Wgl.CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB == Glx.CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB); contextProfile |= Wgl.CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; break; } } #endregion #region WGL_ARB_create_context_robustness|GLX_ARB_create_context_robustness if (hasCreateContextRobustness) { if ((_RobustContextBit == AttributePermission.Enabled) || (debuggerAttached && _RobustContextBit == AttributePermission.EnabledInDebugger)) { Debug.Assert(Wgl.CONTEXT_ROBUST_ACCESS_BIT_ARB == Glx.CONTEXT_ROBUST_ACCESS_BIT_ARB); contextFlags |= Wgl.CONTEXT_ROBUST_ACCESS_BIT_ARB; } } #endregion Debug.Assert(Wgl.CONTEXT_FLAGS_ARB == Glx.CONTEXT_FLAGS_ARB); if (contextFlags != 0) { attributes.AddRange(new int[] { Wgl.CONTEXT_FLAGS_ARB, unchecked ((int)contextFlags) }); } Debug.Assert(Wgl.CONTEXT_PROFILE_MASK_ARB == Glx.CONTEXT_PROFILE_MASK_ARB); if (contextProfile != 0) { attributes.AddRange(new int[] { Wgl.CONTEXT_PROFILE_MASK_ARB, unchecked ((int)contextProfile) }); } attributes.Add(0); if ((_RenderContext = _DeviceContext.CreateContextAttrib(IntPtr.Zero, attributes.ToArray())) == IntPtr.Zero) { throw new InvalidOperationException(String.Format("unable to create render context ({0})", Gl.GetError())); } } else { // Create OpenGL context using compatibility profile if ((_RenderContext = _DeviceContext.CreateContext(IntPtr.Zero)) == IntPtr.Zero) { throw new InvalidOperationException("unable to create render context"); } } }
private DevicePixelFormatCollection GetPixelFormats_ARB_pixel_format(Wgl.Extensions wglExtensions) { // Get the number of pixel formats int[] countFormatAttribsCodes = new int[] { Wgl.NUMBER_PIXEL_FORMATS_ARB }; int[] countFormatAttribsValues = new int[countFormatAttribsCodes.Length]; Wgl.GetPixelFormatAttribARB(_DeviceContext, 1, 0, (uint)countFormatAttribsCodes.Length, countFormatAttribsCodes, countFormatAttribsValues); // Request configurations List<int> pixelFormatAttribsCodes = new List<int>(12); // Minimum requirements pixelFormatAttribsCodes.Add(Wgl.SUPPORT_OPENGL_ARB); // Required to be Gl.TRUE pixelFormatAttribsCodes.Add(Wgl.ACCELERATION_ARB); // Required to be Wgl.FULL_ACCELERATION or Wgl.ACCELERATION_ARB pixelFormatAttribsCodes.Add(Wgl.PIXEL_TYPE_ARB); // Buffer destination pixelFormatAttribsCodes.Add(Wgl.DRAW_TO_WINDOW_ARB); pixelFormatAttribsCodes.Add(Wgl.DRAW_TO_BITMAP_ARB); // Multiple buffers pixelFormatAttribsCodes.Add(Wgl.DOUBLE_BUFFER_ARB); pixelFormatAttribsCodes.Add(Wgl.SWAP_METHOD_ARB); pixelFormatAttribsCodes.Add(Wgl.STEREO_ARB); // Pixel description pixelFormatAttribsCodes.Add(Wgl.COLOR_BITS_ARB); pixelFormatAttribsCodes.Add(Wgl.DEPTH_BITS_ARB); pixelFormatAttribsCodes.Add(Wgl.STENCIL_BITS_ARB); #if SUPPORT_MULTISAMPLE // Multisample extension if (wglExtensions.Multisample_ARB || wglExtensions.Multisample_EXT) { pixelFormatAttribsCodes.Add(Wgl.SAMPLE_BUFFERS_ARB); pixelFormatAttribsCodes.Add(Wgl.SAMPLES_ARB); } int pixelFormatAttribMultisampleIndex = pixelFormatAttribsCodes.Count - 1; #endif #if SUPPORT_PBUFFER if (wglExtensions.Pbuffer_ARB || wglExtensions.Pbuffer_EXT) { pixelFormatAttribsCodes.Add(Wgl.DRAW_TO_PBUFFER_ARB); } int pixelFormatAttribPBufferIndex = pixelFormatAttribsCodes.Count - 1; #endif #if SUPPORT_FRAMEBUFFER_SRGB // Framebuffer sRGB extension if (wglExtensions.FramebufferSRGB_ARB || wglExtensions.FramebufferSRGB_EXT) pixelFormatAttribsCodes.Add(Wgl.FRAMEBUFFER_SRGB_CAPABLE_ARB); int pixelFormatAttribFramebufferSrgbIndex = pixelFormatAttribsCodes.Count - 1; #endif // Create pixel format collection DevicePixelFormatCollection pixelFormats = new DevicePixelFormatCollection(); // Retrieve information about available pixel formats int[] pixelFormatAttribValues = new int[pixelFormatAttribsCodes.Count]; for (int pixelFormatIndex = 1; pixelFormatIndex < countFormatAttribsValues[0]; pixelFormatIndex++) { DevicePixelFormat pixelFormat = new DevicePixelFormat(); Wgl.GetPixelFormatAttribARB(_DeviceContext, pixelFormatIndex, 0, (uint)pixelFormatAttribsCodes.Count, pixelFormatAttribsCodes.ToArray(), pixelFormatAttribValues); // Check minimum requirements if (pixelFormatAttribValues[0] != Gl.TRUE) continue; // No OpenGL support if (pixelFormatAttribValues[1] != Wgl.FULL_ACCELERATION_ARB) continue; // No hardware acceleration switch (pixelFormatAttribValues[2]) { case Wgl.TYPE_RGBA_ARB: #if SUPPORT_PIXEL_FORMAT_FLOAT case Wgl.TYPE_RGBA_FLOAT_ARB: #endif #if SUPPORT_PIXEL_FORMAT_PACKED_FLOAT case Wgl.TYPE_RGBA_UNSIGNED_FLOAT_EXT: #endif break; default: continue; // Ignored pixel type } // Collect pixel format attributes pixelFormat.FormatIndex = pixelFormatIndex; switch (pixelFormatAttribValues[2]) { case Wgl.TYPE_RGBA_ARB: pixelFormat.RgbaUnsigned = true; break; case Wgl.TYPE_RGBA_FLOAT_ARB: pixelFormat.RgbaFloat = true; break; case Wgl.TYPE_RGBA_UNSIGNED_FLOAT_EXT: pixelFormat.RgbaFloat = pixelFormat.RgbaUnsigned = true; break; } pixelFormat.RenderWindow = pixelFormatAttribValues[3] == Gl.TRUE; pixelFormat.RenderBuffer = pixelFormatAttribValues[4] == Gl.TRUE; pixelFormat.DoubleBuffer = pixelFormatAttribValues[5] == Gl.TRUE; pixelFormat.SwapMethod = pixelFormatAttribValues[6]; pixelFormat.StereoBuffer = pixelFormatAttribValues[7] == Gl.TRUE; pixelFormat.ColorBits = pixelFormatAttribValues[8]; pixelFormat.DepthBits = pixelFormatAttribValues[9]; pixelFormat.StencilBits = pixelFormatAttribValues[10]; #if SUPPORT_MULTISAMPLE if (wglExtensions.Multisample_ARB || wglExtensions.Multisample_EXT) { Debug.Assert(pixelFormatAttribMultisampleIndex >= 0); pixelFormat.MultisampleBits = pixelFormatAttribValues[pixelFormatAttribMultisampleIndex]; } #endif #if SUPPORT_PBUFFER if (wglExtensions.Pbuffer_ARB || wglExtensions.Pbuffer_EXT) { Debug.Assert(pixelFormatAttribPBufferIndex >= 0); pixelFormat.RenderPBuffer = pixelFormatAttribValues[pixelFormatAttribPBufferIndex] == Gl.TRUE; } #endif #if SUPPORT_FRAMEBUFFER_SRGB if (wglExtensions.FramebufferSRGB_ARB || wglExtensions.FramebufferSRGB_EXT) { Debug.Assert(pixelFormatAttribFramebufferSrgbIndex >= 0); pixelFormat.SRGBCapable = pixelFormatAttribValues[pixelFormatAttribFramebufferSrgbIndex] != 0; } #endif pixelFormats.Add(pixelFormat); } return (pixelFormats); }