예제 #1
0
			/// <summary>
			/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
			/// </summary>
			public void Dispose()
			{
				if (_Handle != IntPtr.Zero) {
					if (Wgl.CurrentExtensions.Pbuffer_ARB) {
						bool res = Wgl.DestroyPbufferARB(_Handle);
						Debug.Assert(res);
					} else {
						bool res = Wgl.DestroyPbufferEXT(_Handle);
						Debug.Assert(res);
					}
					
					_Handle = IntPtr.Zero;
				}

				if (_DeviceContext != IntPtr.Zero) {
					Wgl.ReleaseDC(IntPtr.Zero, _DeviceContext);
					_DeviceContext = IntPtr.Zero;
				}
			}
예제 #2
0
        /// <summary>
        /// Set the device pixel format.
        /// </summary>
        /// <param name="pixelFormat">
        /// A <see cref="DevicePixelFormat"/> that specifies the pixel format to set.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// Exception thrown if <paramref name="pixelFormat"/> is null.
        /// </exception>
        public override void SetPixelFormat(DevicePixelFormat pixelFormat)
        {
            if (pixelFormat == null)
            {
                throw new ArgumentNullException("pixelFormat");
            }
            if (_PixelFormatSet == true)
            {
                throw new InvalidOperationException("pixel format already set");
            }

#if CHOOSE_PIXEL_FORMAT_FALLBACK
            try {
#endif
            Wgl.PIXELFORMATDESCRIPTOR pDescriptor = new Wgl.PIXELFORMATDESCRIPTOR();

            // Note (from MSDN): Setting the pixel format of a window more than once can lead to significant complications for the Window Manager
            // and for multithread applications, so it is not allowed. An application can only set the pixel format of a window one time. Once a
            // window's pixel format is set, it cannot be changed.

            if (!Wgl.DescribePixelFormat(_DeviceContext, pixelFormat.FormatIndex, (uint)pDescriptor.nSize, ref pDescriptor))
            {
                throw new InvalidOperationException(String.Format("unable to describe pixel format {0}", pixelFormat.FormatIndex), GetPlatformException());
            }

            // Set choosen pixel format
            if (!Wgl.SetPixelFormat(_DeviceContext, pixelFormat.FormatIndex, ref pDescriptor))
            {
                throw new InvalidOperationException(String.Format("unable to set pixel format {0}: {1}", pixelFormat.FormatIndex), GetPlatformException());
            }

#if CHOOSE_PIXEL_FORMAT_FALLBACK
        }

        catch (InvalidOperationException) {
            // Try using default ChoosePixelFormat*
            SetDisplayablePixelFormat(pixelFormat);
        }
#endif

            // Unable to set pixel format again
            _PixelFormatSet = true;
        }
예제 #3
0
		private DevicePixelFormatCollection GetPixelFormats_Win32()
		{
			DevicePixelFormatCollection pixelFormats = new DevicePixelFormatCollection();
			Wgl.PIXELFORMATDESCRIPTOR pixelDescr = new Wgl.PIXELFORMATDESCRIPTOR();
			int pixelFormatsCount = Wgl.DescribePixelFormat(_DeviceContext, 0, 0, ref pixelDescr);

			for (int i = 1; i <= pixelFormatsCount; i++) {
				Wgl.DescribePixelFormat(_DeviceContext, i, (uint)Marshal.SizeOf(typeof(Wgl.PIXELFORMATDESCRIPTOR)), ref pixelDescr);

				if ((pixelDescr.dwFlags & Wgl.PixelFormatDescriptorFlags.SupportOpenGL) == 0)
					continue;

				DevicePixelFormat pixelFormat = new DevicePixelFormat();

				pixelFormat.FormatIndex = i;

				pixelFormat.RgbaUnsigned = true;
				pixelFormat.RgbaFloat = false;

				pixelFormat.RenderWindow = true;
				pixelFormat.RenderBuffer = false;

				pixelFormat.DoubleBuffer = (pixelDescr.dwFlags & Wgl.PixelFormatDescriptorFlags.Doublebuffer) != 0;
				pixelFormat.SwapMethod = 0;
				pixelFormat.StereoBuffer = (pixelDescr.dwFlags & Wgl.PixelFormatDescriptorFlags.Stereo) != 0;

				pixelFormat.ColorBits = pixelDescr.cColorBits;
				pixelFormat.DepthBits = pixelDescr.cDepthBits;
				pixelFormat.StencilBits = pixelDescr.cStencilBits;

				pixelFormat.MultisampleBits = 0;

				pixelFormat.RenderPBuffer = false;

				pixelFormat.SRGBCapable = false;

				pixelFormats.Add(pixelFormat);
			}

			return (pixelFormats);
		}
예제 #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="WindowsDeviceContext"/> class.
        /// </summary>
        /// <param name='window'>
        /// Window.
        /// </param>
        /// <exception cref='ArgumentNullException'>
        /// Is thrown when an argument passed to a method is invalid because it is <see langword="null" /> .
        /// </exception>
        /// <exception cref='InvalidOperationException'>
        /// Is thrown when an operation cannot be performed.
        /// </exception>
        public WindowsDeviceContext(Control window)
        {
            if (window == null)
            {
                throw new ArgumentNullException("window");
            }

            // "Force" handle creation
            if (!window.IsHandleCreated && window.Handle != IntPtr.Zero)
            {
                throw new InvalidOperationException("invalid handle");
            }

            _WindowHandle  = window.Handle;
            _DeviceContext = Wgl.GetDC(window.Handle);

            if (DeviceContext == IntPtr.Zero)
            {
                throw new InvalidOperationException("unable to get any video device context");
            }
        }
예제 #5
0
		/// <summary>
		/// Performs application-defined tasks associated with freeing, releasing, or resetting managed/unmanaged resources.
		/// </summary>
		/// <param name="disposing">
		/// A <see cref="System.Boolean"/> indicating whether the disposition is requested explictly.
		/// </param>
		protected override void Dispose(bool disposing)
		{
			if (disposing) {
				// Release device context
				if (_DeviceContext != IntPtr.Zero) {
					if (_DeviceContextPBuffer == false) {
						bool res = Wgl.ReleaseDC(_WindowHandle, _DeviceContext);
						Debug.Assert(res);
					} else {
						int res = Wgl.ReleasePbufferDCARB(_WindowHandle, _DeviceContext);
						Debug.Assert(res == 1);
					}

					_DeviceContext = IntPtr.Zero;
					_WindowHandle = IntPtr.Zero;
				}
			}

			// Base implementation
			base.Dispose(disposing);
		}
예제 #6
0
            /// <summary>
            /// Construct a NativePBuffer with a specific pixel format and size.
            /// </summary>
            /// <param name="pixelFormat">
            /// A <see cref="DevicePixelFormat"/> that specifies the pixel format and the ancillary buffers required.
            /// </param>
            /// <param name="width">
            /// A <see cref="UInt32"/> that specifies the width of the P-Buffer, in pixels.
            /// </param>
            /// <param name="height">
            /// A <see cref="UInt32"/> that specifies the height of the P-Buffer, in pixels.
            /// </param>
            public NativePBuffer(DevicePixelFormat pixelFormat, uint width, uint height)
            {
                if (pixelFormat == null)
                {
                    throw new ArgumentNullException("pixelFormat");
                }

                if (!Wgl.CurrentExtensions.Pbuffer_ARB && !Wgl.CurrentExtensions.Pbuffer_EXT)
                {
                    throw new NotSupportedException("WGL_(ARB|EXT)_pbuffer not implemented");
                }

                try {
                    // Uses screen device context
                    _DeviceContext = Wgl.GetDC(Gl._NativeWindow.Handle);

                    // Choose appropriate pixel format
                    pixelFormat.RenderWindow  = false;                          // XXX
                    pixelFormat.RenderPBuffer = true;
                    pixelFormat.DoubleBuffer  = true;

                    int pixelFormatIndex = ChoosePixelFormat(_DeviceContext, pixelFormat);

                    if (Wgl.CurrentExtensions.Pbuffer_ARB)
                    {
                        _Handle = Wgl.CreatePbufferARB(_DeviceContext, pixelFormatIndex, (int)width, (int)height, new int[] { 0 });
                    }
                    else
                    {
                        _Handle = Wgl.CreatePbufferEXT(_DeviceContext, pixelFormatIndex, (int)width, (int)height, new int[] { 0 });
                    }
                    if (_Handle == IntPtr.Zero)
                    {
                        throw new InvalidOperationException("unable to create P-Buffer", GetPlatformExceptionCore());
                    }
                } catch {
                    Dispose();
                    throw;
                }
            }
예제 #7
0
		/// <summary>
		/// Set the device pixel format.
		/// </summary>
		/// <param name="pixelFormat">
		/// A <see cref="DevicePixelFormat"/> that specifies the pixel format to set.
		/// </param>
		private static int ChoosePixelFormat(IntPtr deviceContext, DevicePixelFormat pixelFormat)
		{
			if (pixelFormat == null)
				throw new ArgumentNullException("pixelFormat");

			List<int> attribIList = new List<int>();
			List<float> attribFList = new List<float>();
			uint[] countFormatAttribsValues = new uint[1];
			int[] choosenFormats = new int[4];

			attribIList.AddRange(new int[] { Wgl.SUPPORT_OPENGL_ARB, Gl.TRUE });
			if (pixelFormat.RenderWindow)
				attribIList.AddRange(new int[] { Wgl.DRAW_TO_WINDOW_ARB, Gl.TRUE });
			if (pixelFormat.RenderPBuffer)
				attribIList.AddRange(new int[] { Wgl.DRAW_TO_PBUFFER_ARB, Gl.TRUE });

			if (pixelFormat.RgbaUnsigned)
				attribIList.AddRange(new int[] { Wgl.PIXEL_TYPE_ARB, Wgl.TYPE_RGBA_ARB });
			if (pixelFormat.RgbaFloat)
				attribIList.AddRange(new int[] { Wgl.PIXEL_TYPE_ARB, Wgl.TYPE_RGBA_FLOAT_ARB });

			if (pixelFormat.ColorBits > 0)
				attribIList.AddRange(new int[] { Wgl.COLOR_BITS_ARB, pixelFormat.ColorBits });
			if (pixelFormat.DepthBits > 0)
				attribIList.AddRange(new int[] { Wgl.DEPTH_BITS_ARB, pixelFormat.DepthBits });
			if (pixelFormat.StencilBits > 0)
				attribIList.AddRange(new int[] { Wgl.STENCIL_BITS_ARB, pixelFormat.StencilBits });

			if (pixelFormat.DoubleBuffer)
				attribIList.AddRange(new int[] { Wgl.DOUBLE_BUFFER_ARB, pixelFormat.StencilBits });
			attribIList.Add(0);

			// Let choose pixel formats
			if (!Wgl.ChoosePixelFormatARB(deviceContext, attribIList.ToArray(), attribFList.ToArray(), (uint)choosenFormats.Length, choosenFormats, countFormatAttribsValues))
				throw new InvalidOperationException("unable to choose pixel format", GetPlatformExceptionCore());

			return (choosenFormats[0]);
		}
예제 #8
0
        /// <summary>
        /// Initialize LTS information for the calling thread.
        /// </summary>
        public static void InitializeThread()
        {
#if !MONODROID
            if (Egl.IsRequired == false)
            {
                switch (Platform.CurrentPlatformId)
                {
                case Platform.Id.WindowsNT:
                    Wgl.BindAPI();
                    break;

                case Platform.Id.Linux:
                    Glx.BindAPI();
                    break;

                case Platform.Id.MacOS:
                    if (Glx.IsRequired)
                    {
                        Glx.BindAPI();
                    }
                    else
                    {
                        throw new NotSupportedException("platform MacOS not supported without Glx.IsRequired=true");
                    }
                    break;

                case Platform.Id.Android:
                    Egl.BindAPI();
                    break;

                default:
                    throw new NotSupportedException(String.Format("platform {0} not supported", Platform.CurrentPlatformId));
                }
            }
            else
#endif
            Egl.BindAPI();
        }
예제 #9
0
        /// <summary>
        /// Creates a context.
        /// </summary>
        /// <param name="sharedContext">
        /// A <see cref="IntPtr"/> that specify a context that will share objects with the returned one. If
        /// it is IntPtr.Zero, no sharing is performed.
        /// </param>
        /// <returns>
        /// A <see cref="IntPtr"/> that represents the handle of the created context. If the context cannot be
        /// created, it returns IntPtr.Zero.
        /// </returns>
        /// <exception cref="InvalidOperationException">
        /// Exception thrown in the case <paramref name="sharedContext"/> is different from IntPtr.Zero, and the objects
        /// cannot be shared with it.
        /// </exception>
        public override IntPtr CreateContext(IntPtr sharedContext)
        {
            IntPtr renderContext = IntPtr.Zero;

            try {
                renderContext = Wgl.CreateContext(DeviceContext);
                if ((renderContext != IntPtr.Zero) && (sharedContext != IntPtr.Zero))
                {
                    bool res = Wgl.ShareLists(renderContext, sharedContext);
                    Debug.Assert(res);
                }

                return(renderContext);
            } catch {
                if (renderContext != IntPtr.Zero)
                {
                    bool res = Wgl.DeleteContext(renderContext);
                    Debug.Assert(res);
                }

                throw;
            }
        }
예제 #10
0
		/// <summary>
		/// Set pixel format by letting the driver choose the best pixel format following the criteria.
		/// </summary>
		/// <param name="pixelFormat">
		/// 
		/// </param>
		private void SetDisplayablePixelFormat(DevicePixelFormat pixelFormat)
		{
			if (pixelFormat == null)
				throw new ArgumentNullException("pixelFormat");

			List<int> attribIList = new List<int>();
			List<float> attribFList = new List<float>();
			Wgl.PIXELFORMATDESCRIPTOR pDescriptor = new Wgl.PIXELFORMATDESCRIPTOR();
			uint[] countFormatAttribsValues = new uint[1];
			int[] choosenFormats = new int[4];

			// Let choose pixel formats
			if (!Wgl.ChoosePixelFormatARB(_DeviceContext, attribIList.ToArray(), attribFList.ToArray(), (uint)choosenFormats.Length, choosenFormats, countFormatAttribsValues)) {
				Win32Exception innerException = new Win32Exception(Marshal.GetLastWin32Error());
				throw new InvalidOperationException(String.Format("unable to choose pixel format: {0}", innerException.Message), innerException);
			}
			
			// Set choosen pixel format
			if (Wgl.SetPixelFormat(_DeviceContext, choosenFormats[0], ref pDescriptor) == false) {
				Win32Exception innerException = new Win32Exception(Marshal.GetLastWin32Error());
				throw new InvalidOperationException(String.Format("unable to set pixel format {0}: {1}", pixelFormat.FormatIndex, innerException.Message), innerException);
			}
		}
예제 #11
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DeviceContextWGL"/> class.
        /// </summary>
        /// <param name='nativeBuffer'>
        /// A <see cref="INativePBuffer"/> that specifies the P-Buffer used to create the device context.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// Exception thrown if <paramref name="nativeBuffer"/> is null.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// Exception thrown if <paramref name="nativeBuffer"/> is not an instance created by
        /// <see cref="DeviceContext.CreatePBuffer(DevicePixelFormat, uint, uint)"/>.
        /// </exception>
        /// <exception cref='InvalidOperationException'>
        /// Is thrown when an operation cannot be performed.
        /// </exception>
        public DeviceContextWGL(INativePBuffer nativeBuffer)
        {
            if (nativeBuffer == null)
            {
                throw new ArgumentNullException("nativeBuffer");
            }

            NativePBuffer nativePBuffer = nativeBuffer as NativePBuffer;

            if (nativePBuffer == null)
            {
                throw new ArgumentException("INativePBuffer not created with DeviceContext.CreatePBuffer");
            }

            if (!Wgl.CurrentExtensions.Pbuffer_ARB && !Wgl.CurrentExtensions.Pbuffer_EXT)
            {
                throw new InvalidOperationException("WGL_(ARB|EXT)_pbuffer not supported");
            }

            _WindowHandle = nativePBuffer.Handle;

            if (Wgl.CurrentExtensions.Pbuffer_ARB)
            {
                _DeviceContext = Wgl.GetPbufferDCARB(nativePBuffer.Handle);
            }
            else
            {
                _DeviceContext = Wgl.GetPbufferDCEXT(nativePBuffer.Handle);
            }

            if (_DeviceContext == IntPtr.Zero)
            {
                throw new InvalidOperationException("unable to get device context");
            }
            _DeviceContextPBuffer = true;
        }
예제 #12
0
        /// <summary>
        /// Creates a context, specifying attributes.
        /// </summary>
        /// <param name="sharedContext">
        /// A <see cref="IntPtr"/> that specify a context that will share objects with the returned one. If
        /// it is IntPtr.Zero, no sharing is performed.
        /// </param>
        /// <param name="attribsList">
        /// A <see cref="T:Int32[]"/> that specifies the attributes list.
        /// </param>
        /// <param name="api">
        /// A <see cref="KhronosVersion"/> that specifies the API to be implemented by the returned context. It can be null indicating the
        /// default API for this DeviceContext implementation. If it is possible, try to determine the API version also.
        /// </param>
        /// <returns>
        /// A <see cref="IntPtr"/> that represents the handle of the created context. If the context cannot be
        /// created, it returns IntPtr.Zero.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// Exception thrown if <see cref="attribsList"/> is null.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// Exception thrown if <paramref name="attribsList"/> length is zero or if the last item of <paramref name="attribsList"/>
        /// is not zero.
        /// </exception>
        public override IntPtr CreateContextAttrib(IntPtr sharedContext, int[] attribsList, KhronosVersion api)
        {
            if ((attribsList != null) && (attribsList.Length == 0))
            {
                throw new ArgumentException("zero length array", "attribsList");
            }
            if ((attribsList != null) && (attribsList[attribsList.Length - 1] != 0))
            {
                throw new ArgumentException("not zero-terminated array", "attribsList");
            }

            if (api != null && api.Api != KhronosVersion.ApiGl)
            {
                List <int> adulteredAttribs = new List <int>(attribsList);

                // Support check
                switch (api.Api)
                {
                case KhronosVersion.ApiGles1:
                case KhronosVersion.ApiGles2:
                    if (Wgl.CurrentExtensions.CreateContextEsProfile_EXT == false)
                    {
                        throw new NotSupportedException("OpenGL ES API not supported");
                    }
                    break;

                default:
                    throw new NotSupportedException(String.Format("'{0}' API not supported", api.Api));
                }

                // Remove trailing 0
                if (adulteredAttribs.Count > 0 && adulteredAttribs[adulteredAttribs.Count - 1] == Gl.NONE)
                {
                    adulteredAttribs.RemoveAt(adulteredAttribs.Count - 1);
                }

                // Add required attributes
                int majorVersionIndex = adulteredAttribs.FindIndex(delegate(int item) { return(item == Wgl.CONTEXT_MAJOR_VERSION_ARB); });
                int minorVersionIndex = adulteredAttribs.FindIndex(delegate(int item) { return(item == Wgl.CONTEXT_MINOR_VERSION_ARB); });
                int profileMaskIndex  = adulteredAttribs.FindIndex(delegate(int item) { return(item == Wgl.CONTEXT_PROFILE_MASK_ARB); });

                if (majorVersionIndex < 0)
                {
                    adulteredAttribs.AddRange(new int[] { Gl.MAJOR_VERSION, api.Major });
                    majorVersionIndex = adulteredAttribs.Count - 2;
                }

                if (minorVersionIndex < 0)
                {
                    adulteredAttribs.AddRange(new int[] { Gl.MINOR_VERSION, api.Minor });
                    minorVersionIndex = adulteredAttribs.Count - 2;
                }

                if (profileMaskIndex < 0)
                {
                    adulteredAttribs.AddRange(new int[] { Gl.CONTEXT_PROFILE_MASK, 0 });
                    profileMaskIndex = adulteredAttribs.Count - 2;
                }

                switch (api.Api)
                {
                case KhronosVersion.ApiGles1:
                    // Ignore API version: force always to 1.0
                    adulteredAttribs[majorVersionIndex + 1] = 1;
                    adulteredAttribs[minorVersionIndex + 1] = 0;
                    adulteredAttribs[profileMaskIndex + 1] |= (int)Wgl.CONTEXT_ES_PROFILE_BIT_EXT;
                    break;

                case KhronosVersion.ApiGles2:
                    // Uses API version: it may be greater than 2.0(?)
                    adulteredAttribs[majorVersionIndex + 1] = 2;
                    adulteredAttribs[minorVersionIndex + 1] = 0;
                    adulteredAttribs[profileMaskIndex + 1] |= (int)Wgl.CONTEXT_ES_PROFILE_BIT_EXT;
                    break;

                default:
                    Debug.Fail("API not implemented");
                    throw new NotSupportedException(String.Format("'{0}' API not supported", api.Api));
                }

                // Restore trailing 0
                adulteredAttribs.Add(Gl.NONE);

                return(Wgl.CreateContextAttribsARB(_DeviceContext, sharedContext, adulteredAttribs.ToArray()));
            }
            else
            {
                return(Wgl.CreateContextAttribsARB(_DeviceContext, sharedContext, attribsList));
            }
        }
예제 #13
0
 /// <summary>
 /// Control the the buffers swap of a device.
 /// </summary>
 /// <param name="interval">
 /// A <see cref="System.Int32"/> that specifies the minimum number of video frames that are displayed
 /// before a buffer swap will occur.
 /// </param>
 /// <returns>
 /// It returns a boolean value indicating whether the operation was successful.
 /// </returns>
 public override bool SwapInterval(int interval)
 {
     return(Wgl.SwapIntervalEXT(interval));
 }
예제 #14
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);
		}
예제 #15
0
		/// <summary>
		/// Creates a context, specifying attributes.
		/// </summary>
		/// <param name="sharedContext">
		/// A <see cref="IntPtr"/> that specify a context that will share objects with the returned one. If
		/// it is IntPtr.Zero, no sharing is performed.
		/// </param>
		/// <param name="attribsList">
		/// A <see cref="T:Int32[]"/> that specifies the attributes list.
		/// </param>
		/// <param name="api">
		/// A <see cref="KhronosVersion"/> that specifies the API to be implemented by the returned context. It can be null indicating the
		/// default API for this DeviceContext implementation. If it is possible, try to determine the API version also.
		/// </param>
		/// <returns>
		/// A <see cref="IntPtr"/> that represents the handle of the created context. If the context cannot be
		/// created, it returns IntPtr.Zero.
		/// </returns>
		/// <exception cref="ArgumentNullException">
		/// Exception thrown if <see cref="attribsList"/> is null.
		/// </exception>
		/// <exception cref="ArgumentException">
		/// Exception thrown if <paramref name="attribsList"/> length is zero or if the last item of <paramref name="attribsList"/>
		/// is not zero.
		/// </exception>
		public override IntPtr CreateContextAttrib(IntPtr sharedContext, int[] attribsList, KhronosVersion api)
		{
			if (Wgl.CurrentExtensions != null && Wgl.CurrentExtensions.CreateContext_ARB == false)
				throw new InvalidOperationException("WGL_ARB_create_context not supported");
			if ((attribsList != null) && (attribsList.Length == 0))
				throw new ArgumentException("zero length array", "attribsList");
			if ((attribsList != null) && (attribsList[attribsList.Length - 1] != Gl.NONE))
				throw new ArgumentException("not zero-terminated array", "attribsList");

			// Defaults null attributes
			if (attribsList == null)
				attribsList = new int[] { Gl.NONE };

			if (api != null) {
				List<int> adulteredAttribs = new List<int>(attribsList);

				// Support check
				switch (api.Api) {
					case KhronosVersion.ApiGl:
						break;
					case KhronosVersion.ApiGles1:
					case KhronosVersion.ApiGles2:
					case KhronosVersion.ApiGlsc2:
						if (Wgl.CurrentExtensions.CreateContextEsProfile_EXT == false)
							throw new NotSupportedException("OpenGL ES API not supported");
						break;
					default:
						throw new NotSupportedException(String.Format("'{0}' API not supported", api.Api));
				}

				// Remove trailing 0
				if (adulteredAttribs.Count > 0 && adulteredAttribs[adulteredAttribs.Count - 1] == Gl.NONE)
					adulteredAttribs.RemoveAt(adulteredAttribs.Count - 1);

				// Add required attributes
				int major = api.Major, minor = api.Minor, profileMask = 0;

				switch (api.Api) {
					case KhronosVersion.ApiGl:
						switch (api.Profile) {
							case KhronosVersion.ProfileCompatibility:
								profileMask |= (int)Wgl.CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
								break;
							case KhronosVersion.ProfileCore:
								profileMask |= (int)Wgl.CONTEXT_CORE_PROFILE_BIT_ARB;
								break;
							case null:
								// No specific profile required, leaving the default (core profile)
								break;
							default:
								throw new NotSupportedException(String.Format("'{0}' Profile not supported", api.Profile));
						}
						break;
					case KhronosVersion.ApiGles1:
						// Ignore API version: force always to 1.0
						major = 1;
						minor = 0;
						profileMask |= (int)Wgl.CONTEXT_ES_PROFILE_BIT_EXT;
						break;
					case KhronosVersion.ApiGles2:
					case KhronosVersion.ApiGlsc2:
						major = 2;
						minor = 0;
						profileMask |= (int)Wgl.CONTEXT_ES_PROFILE_BIT_EXT;
						break;
					default:
						Debug.Fail("API not implemented");
						throw new NotSupportedException(String.Format("'{0}' API not supported", api.Api));
				}

				// Add/Replace attributes
				int majorVersionIndex, minorVersionIndex, profileMaskIndex;

				if ((majorVersionIndex = adulteredAttribs.FindIndex(delegate (int item) {
					return (item == Wgl.CONTEXT_MAJOR_VERSION_ARB);
				})) >= 0)
					adulteredAttribs[majorVersionIndex + 1] = major;
				else
					adulteredAttribs.AddRange(new int[] { Wgl.CONTEXT_MAJOR_VERSION_ARB, major });

				if ((minorVersionIndex = adulteredAttribs.FindIndex(delegate (int item) {
					return (item == Wgl.CONTEXT_MINOR_VERSION_ARB);
				})) >= 0)
					adulteredAttribs[minorVersionIndex + 1] = minor;
				else
					adulteredAttribs.AddRange(new int[] { Wgl.CONTEXT_MINOR_VERSION_ARB, api.Minor });

				if (profileMask != 0) {
					if ((profileMaskIndex = adulteredAttribs.FindIndex(delegate (int item) {
						return (item == Wgl.CONTEXT_PROFILE_MASK_ARB);
					})) >= 0)
						adulteredAttribs[profileMaskIndex + 1] = profileMask;
					else
						adulteredAttribs.AddRange(new int[] { Wgl.CONTEXT_PROFILE_MASK_ARB, profileMask });
				}

				// Restore trailing 0
				adulteredAttribs.Add(Gl.NONE);

				return (Wgl.CreateContextAttribsARB(_DeviceContext, sharedContext, adulteredAttribs.ToArray()));
			} else
				return (Wgl.CreateContextAttribsARB(_DeviceContext, sharedContext, attribsList));
		}
예제 #16
0
 /// <summary>
 /// Makes the context current on the calling thread.
 /// </summary>
 /// <param name="ctx">
 /// A <see cref="IntPtr"/> that specify the context to be current on the calling thread, bound to
 /// thise device context. It can be IntPtr.Zero indicating that no context will be current.
 /// </param>
 /// <returns>
 /// It returns a boolean value indicating whether the operation was successful.
 /// </returns>
 /// <exception cref="NotSupportedException">
 /// Exception thrown if the current platform is not supported.
 /// </exception>
 protected override bool MakeCurrentCore(IntPtr ctx)
 {
     return(Wgl.MakeCurrent(_DeviceContext, ctx));
 }
예제 #17
0
파일: Gl.cs 프로젝트: antoinecla/OpenGL.Net
        /// <summary>
        /// Initialize OpenGL namespace static environment. This method shall be called before any other classes methods.
        /// </summary>
        public static void Initialize()
        {
            if (_Initialized == true)
            {
                return;                 // Already initialized
            }
            _Initialized = true;
#if !NETSTANDARD1_1
            // Optional initialization
            string envGlInit = Environment.GetEnvironmentVariable("OPENGL_NET_INIT");
            if (envGlInit != null && envGlInit == "NO")
            {
                return;
            }
#endif
            // Environment options
            LogComment("OpenGL.Net is initializing");

            // Loader function			OS API			GL API
            // ------------------------------------------------------
            // Supported platform: Windows
            // wglGetProcAddress		WGL				GL
            // wglGetProcAddress		WGL				GLES2+ (with WGL_create_context_es(2)?_profile_EXT)
            // eglGetProcAddress		EGL(Angle)		GLES2+
            // ------------------------------------------------------
            // Supported platform: Linux
            // glXGetProcAddress		GLX				GL
            // glXGetProcAddress		GLX				GLES2+ (with GLX_create_context_es(2)?_profile_EXT)
            // eglGetProcAddress		EGL				GLES2+
            // ------------------------------------------------------
            // Supported platform: Android
            // eglGetProcAddress		EGL				GL
            // eglGetProcAddress		EGL				GLES2+

            try {
#if !MONODROID
                // Determine whether use EGL as device context backend
                if (Egl.IsAvailable)
                {
                    switch (Platform.CurrentPlatformId)
                    {
                    case Platform.Id.Linux:
                        if (Glx.IsAvailable == false)
                        {
                            Egl.IsRequired = true;
                        }
                        break;
                    }
                }
#endif

                // Create native window for getting preliminary information on desktop systems
                // This instance will be used for creating contexts without explictly specify a window
                _NativeWindow = DeviceContext.CreateHiddenWindow();

                // Create device context
                using (DeviceContext windowDevice = DeviceContext.Create()) {
                    // Create basic OpenGL context
                    IntPtr renderContext = windowDevice.CreateSimpleContext();
                    if (renderContext == IntPtr.Zero)
                    {
                        throw new NotImplementedException("unable to create a simple context");
                    }

                    // Make contect current
                    if (windowDevice.MakeCurrent(renderContext) == false)
                    {
                        throw new InvalidOperationException("unable to make current", windowDevice.GetPlatformException());
                    }

#if !MONODROID
                    // Reload platform function pointers, if required
                    if (Egl.IsRequired == false)
                    {
                        switch (Platform.CurrentPlatformId)
                        {
                        case Platform.Id.WindowsNT:
                            Wgl.BindAPI();
                            break;
                        }
                    }
#endif

                    // Query OpenGL informations
                    string glVersion = GetString(StringName.Version);
                    _CurrentVersion = KhronosVersion.Parse(glVersion);

                    // Query OpenGL extensions (current OpenGL implementation, CurrentCaps)
                    _CurrentExtensions = new Extensions();
                    _CurrentExtensions.Query();
                    // Query platform extensions
                    windowDevice.QueryPlatformExtensions();
                    // Query OpenGL limits
                    _CurrentLimits = Limits.Query(Gl.CurrentVersion, _CurrentExtensions);

                    // Obtain current OpenGL Shading Language version
                    string glslVersion = null;

                    switch (_CurrentVersion.Api)
                    {
                    case KhronosVersion.ApiGl:
                        if (_CurrentVersion >= Version_200 || _CurrentExtensions.ShadingLanguage100_ARB)
                        {
                            glslVersion = GetString(StringName.ShadingLanguageVersion);
                        }
                        break;

                    case KhronosVersion.ApiGles2:
                        glslVersion = GetString(StringName.ShadingLanguageVersion);
                        break;
                    }

                    if (glslVersion != null)
                    {
                        _CurrentShadingVersion = GlslVersion.Parse(glslVersion, _CurrentVersion.Api);
                    }

                    // Vendor/Render information
                    _Vendor   = GetString(StringName.Vendor);
                    _Renderer = GetString(StringName.Renderer);

                    if (EnvDebug || EnvExperimental)
                    {
                        Debug.Assert(CurrentVersion != null && CurrentExtensions != null);
                        CheckExtensionCommands <Gl>(CurrentVersion, CurrentExtensions, EnvExperimental);
                    }

                    // Before deletion, make uncurrent
                    windowDevice.MakeCurrent(IntPtr.Zero);
                    // Detroy context
                    if (windowDevice.DeleteContext(renderContext) == false)
                    {
                        throw new InvalidOperationException("unable to delete OpenGL context");
                    }
                }

                LogComment("OpenGL.Net has been initialized");
            } catch (Exception excepton) {
                _InitializationException = excepton;
                LogComment("Unable to initialize OpenGL.Net: {0}", _InitializationException.ToString());
            }
        }
예제 #18
0
 /// <summary>
 /// Makes the context current on the calling thread.
 /// </summary>
 /// <param name="ctx">
 /// A <see cref="IntPtr"/> that specify the context to be current on the calling thread, bound to
 /// thise device context. It can be IntPtr.Zero indicating that no context will be current.
 /// </param>
 /// <returns>
 /// It returns a boolean value indicating whether the operation was successful.
 /// </returns>
 /// <exception cref="NotSupportedException">
 /// Exception thrown if the current platform is not supported.
 /// </exception>
 public override bool MakeCurrent(IntPtr ctx)
 {
     return(Wgl.MakeCurrent(DeviceContext, ctx));
 }