Axiom.RenderSystems.OpenGL.GLFBORTTManager._detectFBOFormats C# (CSharp) Method

_detectFBOFormats() private method

Detect allowed FBO formats
private _detectFBOFormats ( ) : void
return void
		private void _detectFBOFormats()
		{
			// Try all formats, and report which ones work as target
			int fb, tid;
			int old_drawbuffer, old_readbuffer;
			int target = Gl.GL_TEXTURE_2D;

			Gl.glGetIntegerv( Gl.GL_DRAW_BUFFER, out old_drawbuffer );
			Gl.glGetIntegerv( Gl.GL_READ_BUFFER, out old_readbuffer );

			for ( int x = 0; x < (int)PixelFormat.Count; ++x )
			{
				_props[ x ].Valid = false;

				// Fetch GL format token
				int fmt = GLPixelUtil.GetGLInternalFormat( (PixelFormat)x );
				if ( fmt == Gl.GL_NONE && x != 0 )
					continue;

				// No test for compressed formats
				if ( PixelUtil.IsCompressed( (PixelFormat)x ) )
					continue;

				// Buggy ATI cards *crash* on non-RGB(A) formats
				int[] depths = PixelUtil.GetBitDepths( (PixelFormat)x );
				if ( fmt != Gl.GL_NONE && _atiMode && ( depths[ 0 ] == 0 || depths[ 1 ] == 0 || depths[ 2 ] == 0 ) )
					continue;

				// Buggy NVidia Drivers fail on 32Bit FP formats on Windows.
				if ( PixelUtil.IsFloatingPoint( (PixelFormat)x ) && PlatformManager.IsWindowsOS && !_atiMode )
					continue;

				// Create and attach framebuffer
				Gl.glGenFramebuffersEXT( 1, out fb );
				Gl.glBindFramebufferEXT( Gl.GL_FRAMEBUFFER_EXT, fb );
				if ( fmt != Gl.GL_NONE )
				{
					// Create and attach texture
					Gl.glGenTextures( 1, out tid );
					Gl.glBindTexture( target, tid );

					// Set some default parameters so it won't fail on NVidia cards
					Gl.glTexParameteri( target, Gl.GL_TEXTURE_MAX_LEVEL, 0 );
					Gl.glTexParameteri( target, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_NEAREST );
					Gl.glTexParameteri( target, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_NEAREST );
					Gl.glTexParameteri( target, Gl.GL_TEXTURE_WRAP_S, Gl.GL_CLAMP_TO_EDGE );
					Gl.glTexParameteri( target, Gl.GL_TEXTURE_WRAP_T, Gl.GL_CLAMP_TO_EDGE );

					Gl.glTexImage2D( target, 0, fmt, PROBE_SIZE, PROBE_SIZE, 0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, IntPtr.Zero );
					Gl.glFramebufferTexture2DEXT( Gl.GL_FRAMEBUFFER_EXT, Gl.GL_COLOR_ATTACHMENT0_EXT, target, tid, 0 );
				}
				else
				{
					// Draw to nowhere -- stencil/depth only
					tid = 0;
					Gl.glDrawBuffer( Gl.GL_NONE );
					Gl.glReadBuffer( Gl.GL_NONE );
				}
				// Check status
				int status = Gl.glCheckFramebufferStatusEXT( Gl.GL_FRAMEBUFFER_EXT );

				// Ignore status in case of fmt==GL_NONE, because no implementation will accept
				// a buffer without *any* attachment. Buffers with only stencil and depth attachment
				// might still be supported, so we must continue probing.
				if ( fmt == Gl.GL_NONE || status == Gl.GL_FRAMEBUFFER_COMPLETE_EXT )
				{
					_props[ x ].Valid = true;
					StringBuilder str = new StringBuilder();
					str.AppendFormat( "\tFBO {0} depth/stencil support: ", PixelUtil.GetFormatName( (PixelFormat)x ) );

					// For each depth/stencil formats
					for ( int depth = 0; depth < _depthFormats.GetLength( 0 ); ++depth )
					{
						if ( _depthFormats[ depth ] != GL_DEPTH24_STENCIL8_EXT )
						{
							// General depth/stencil combination

							for ( int stencil = 0; stencil < _stencilFormats.GetLength( 0 ); ++stencil )
							{
								//LogManager.Instance.Write( "Trying {0} D{1}S{2} ", PixelUtil.GetFormatName( (PixelFormat)x ), _depthBits[ depth ], _stencilBits[ stencil ] );

								if ( _tryFormat( _depthFormats[ depth ], _stencilFormats[ stencil ] ) )
								{
									/// Add mode to allowed modes
									str.AppendFormat( "D{0}S{1} ", _depthBits[ depth ], _stencilBits[ stencil ] );
									FormatProperties.Mode mode;
									mode.Depth = depth;
									mode.Stencil = stencil;
									_props[ x ].Modes.Add( mode );
								}
							}
						}
						else
						{
							// Packed depth/stencil format
#if false
                            // Only query packed depth/stencil formats for 32-bit
                            // non-floating point formats (ie not R32!)
                            // Linux nVidia driver segfaults if you query others
							if ( !PlatformManager.IsWindowsOS &&
								 ( PixelUtil.GetNumElemBits( (PixelFormat)x ) != 32 ||
								   PixelUtil.IsFloatingPoint( (PixelFormat)x ) ) )
							{
								continue;
							}
#endif
							if ( _tryPackedFormat( _depthFormats[ depth ] ) )
							{
								/// Add mode to allowed modes
								str.AppendFormat( "Packed-D{0}S8 ", _depthBits[ depth ] );
								FormatProperties.Mode mode;
								mode.Depth = depth;
								mode.Stencil = 0;   // unuse
								_props[ x ].Modes.Add( mode );
							}
						}
					}

					LogManager.Instance.Write( str.ToString() );

				}
				// Delete texture and framebuffer
				Gl.glBindFramebufferEXT( Gl.GL_FRAMEBUFFER_EXT, 0 );
				Gl.glDeleteFramebuffersEXT( 1, ref fb );

				// Workaround for NVIDIA / Linux 169.21 driver problem
				// see http://www.ogre3d.org/phpBB2/viewtopic.php?t=38037&start=25
				Gl.glFinish();

				Gl.glDeleteTextures( 1, ref tid );
			}

			// It seems a bug in nVidia driver: glBindFramebufferEXT should restore
			// draw and read buffers, but in some unclear circumstances it won't.
			Gl.glDrawBuffer( old_drawbuffer );
			Gl.glReadBuffer( old_readbuffer );

			string fmtstring = "";
			for ( int x = 0; x < (int)PixelFormat.Count; ++x )
			{
				if ( _props[ x ].Valid )
					fmtstring += PixelUtil.GetFormatName( (PixelFormat)x ) + " ";
			}
			LogManager.Instance.Write( "[GL] : Valid FBO targets " + fmtstring );

		}