Ejemplo n.º 1
0
        /// <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");
                }
            }
        }
Ejemplo n.º 2
0
		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);
		}