private void CheckCaps( RenderTarget primary )
{
_rsCapabilities = new RenderSystemCapabilities();
_rsCapabilities.DeviceName = OpenTK.Graphics.ES11.GL.GetString( All.Renderer );
_rsCapabilities.VendorName = OpenTK.Graphics.ES11.GL.GetString( All.Vendor );
_rsCapabilities.RendersystemName = Name;
// GL ES 1.x is fixed function only
_rsCapabilities.SetCapability( Capabilities.FixedFunction );
// Multitexturing support and set number of texture units
int units = 0;
OpenGL.GetInteger( All.MaxTextureUnits, ref units );
_rsCapabilities.TextureUnitCount = units;
// Check for hardware stencil support and set bit depth
int stencil = 0;
OpenGL.GetInteger( All.StencilBits, ref stencil );
GLESConfig.GlCheckError( this );
if ( stencil != 0 )
{
_rsCapabilities.SetCapability( Capabilities.StencilBuffer );
_rsCapabilities.StencilBufferBitCount = stencil;
}
// Scissor test is standard
_rsCapabilities.SetCapability( Capabilities.ScissorTest );
// Vertex Buffer Objects are always supported by OpenGL ES
_rsCapabilities.SetCapability( Capabilities.VertexBuffer );
// OpenGL ES - Check for these extensions too
// For 1.1, http://www.khronos.org/registry/gles/api/1.1/glext.h
// For 2.0, http://www.khronos.org/registry/gles/api/2.0/gl2ext.h
if ( _glSupport.CheckExtension( "GL_IMG_texture_compression_pvrtc" ) ||
_glSupport.CheckExtension( "GL_AMD_compressed_3DC_texture" ) ||
_glSupport.CheckExtension( "GL_AMD_compressed_ATC_texture" ) ||
_glSupport.CheckExtension( "GL_OES_compressed_ETC1_RGB8_texture" ) ||
_glSupport.CheckExtension( "GL_OES_compressed_paletted_texture" ) )
{
// TODO: Add support for compression types other than pvrtc
_rsCapabilities.SetCapability( Capabilities.TextureCompression );
if ( _glSupport.CheckExtension( "GL_IMG_texture_compression_pvrtc" ) )
_rsCapabilities.SetCapability( Capabilities.TextureCompressionPVRTC );
}
if ( _glSupport.CheckExtension( "GL_EXT_texture_filter_anisotropic" ) )
_rsCapabilities.SetCapability( Capabilities.AnisotropicFiltering );
if ( _glSupport.CheckExtension( "GL_OES_framebuffer_object" ) )
{
LogManager.Instance.Write( "[GLES] Framebuffers are supported." );
_rsCapabilities.SetCapability( Capabilities.FrameBufferObjects );
_rsCapabilities.SetCapability( Capabilities.HardwareRenderToTexture );
}
else
{
_rsCapabilities.SetCapability( Capabilities.PBuffer );
_rsCapabilities.SetCapability( Capabilities.HardwareRenderToTexture );
}
// Cube map
if ( _glSupport.CheckExtension( "GL_OES_texture_cube_map" ) )
_rsCapabilities.SetCapability( Capabilities.CubeMapping );
if ( _glSupport.CheckExtension( "GL_OES_stencil_wrap" ) )
_rsCapabilities.SetCapability( Capabilities.StencilWrap );
if ( _glSupport.CheckExtension( "GL_OES_blend_subtract" ) )
_rsCapabilities.SetCapability( Capabilities.AdvancedBlendOperations );
if ( _glSupport.CheckExtension( "GL_ANDROID_user_clip_plane" ) )
_rsCapabilities.SetCapability( Capabilities.UserClipPlanes );
if ( _glSupport.CheckExtension( "GL_OES_texture3D" ) )
_rsCapabilities.SetCapability( Capabilities.Texture3D );
// GL always shares vertex and fragment texture units (for now?)
_rsCapabilities.VertexTextureUnitsShared = true;
// Hardware support mipmapping
_rsCapabilities.SetCapability( Capabilities.Automipmap );
if ( _glSupport.CheckExtension( "GL_EXT_texture_lod_bias" ) )
_rsCapabilities.SetCapability( Capabilities.MipmapLODBias );
//blending support
_rsCapabilities.SetCapability( Capabilities.TextureBlending );
// DOT3 support is standard
_rsCapabilities.SetCapability( Capabilities.Dot3 );
if ( _rsCapabilities.HasCapability( Capabilities.VertexBuffer ) )
{
hardwareBufferManager = new GLESHardwareBufferManager();
}
else
{
hardwareBufferManager = new GLESDefaultHardwareBufferManager();
}
/// Do this after extension function pointers are initialised as the extension
/// is used to probe further capabilities.
int rttMode = 0;
if ( ConfigOptions.ContainsKey( "RTT Preferred Mode" ) )
{
ConfigOption opt = ConfigOptions[ "RTT Preferred Mode" ];
// RTT Mode: 0 use whatever available, 1 use PBuffers, 2 force use copying
if ( opt.Value == "PBuffer" )
{
rttMode = 1;
}
else if ( opt.Value == "Copy" )
{
rttMode = 2;
}
}
LogManager.Instance.Write( "[GLES] 'RTT Preferred Mode' = {0}", rttMode );
// Check for framebuffer object extension
if ( _rsCapabilities.HasCapability( Capabilities.FrameBufferObjects ) && ( rttMode < 1 ) )
{
if ( _rsCapabilities.HasCapability( Capabilities.HardwareRenderToTexture ) )
{
// Create FBO manager
LogManager.Instance.Write( "[GLES] Using GL_OES_framebuffer_object for rendering to textures (best)" );
_rttManager = new GLESFBORTTManager();
}
}
else
{
// Check GLSupport for PBuffer support
if ( _rsCapabilities.HasCapability( Capabilities.PBuffer ) && rttMode < 2 )
{
if ( _rsCapabilities.HasCapability( Capabilities.HardwareRenderToTexture ) )
{
// Use PBuffers
_rttManager = new GLESPBRTTManager();
LogManager.Instance.Write( "[GLES] Using PBuffers for rendering to textures" );
}
}
else
{
// No pbuffer support either -- fallback to simplest copying from framebuffer
_rttManager = new GLESCopyingRTTManager();
LogManager.Instance.Write( "[GLES] Using framebuffer copy for rendering to textures (worst)" );
LogManager.Instance.Write( "[GLES] Warning: RenderTexture size is restricted to size of framebuffer." );
}
_rsCapabilities.MultiRenderTargetCount = 1;
}
// Point size
float ps = 0;
OpenGL.GetFloat( All.PointSizeMax, ref ps );
GLESConfig.GlCheckError( this );
_rsCapabilities.MaxPointSize = ps;
// Point sprites
if ( _glSupport.CheckExtension( "GL_OES_point_sprite" ) )
_rsCapabilities.SetCapability( Capabilities.PointSprites );
_rsCapabilities.SetCapability( Capabilities.PointExtendedParameters );
// UBYTE4 always supported
_rsCapabilities.SetCapability( Capabilities.VertexFormatUByte4 );
// Infinite far plane always supported
_rsCapabilities.SetCapability( Capabilities.InfiniteFarPlane );
// hardware occlusion support
_rsCapabilities.SetCapability( Capabilities.HardwareOcculusion );
//// Check for Float textures
if ( _glSupport.CheckExtension( "GL_OES_texture_half_float" ) )
_rsCapabilities.SetCapability( Capabilities.TextureFloat );
// Alpha to coverage always 'supported' when MSAA is available
// although card may ignore it if it doesn't specifically support A2C
_rsCapabilities.SetCapability( Capabilities.AlphaToCoverage );
}