protected override void createInternalResources()
{
// Convert to nearest power-of-two size if required
Width = GLESPixelUtil.OptionalPO2( Width );
Height = GLESPixelUtil.OptionalPO2( Height );
Depth = GLESPixelUtil.OptionalPO2( Depth );
//adjust format if required
Format = TextureManager.Instance.GetNativeFormat( Graphics.TextureType.TwoD, Format, Usage );
// Check requested number of mipmaps
int maxMips = GLESPixelUtil.GetMaxMipmaps( Width, Height, Depth, Format );
if ( PixelUtil.IsCompressed( Format ) && _mipmapCount == 0 )
RequestedMipmapCount = 0;
_mipmapCount = RequestedMipmapCount;
if ( _mipmapCount > maxMips )
_mipmapCount = maxMips;
// Generate texture name
OpenGL.GenTextures( 1, ref _textureID );
GLESConfig.GlCheckError( this );
// Set texture type
OpenGL.BindTexture( All.Texture2D, _textureID );
GLESConfig.GlCheckError( this );
// Set some misc default parameters, these can of course be changed later
OpenGL.TexParameter( All.Texture2D, All.TextureMinFilter, (int)All.LinearMipmapNearest );
GLESConfig.GlCheckError( this );
OpenGL.TexParameter( All.Texture2D, All.TextureMagFilter, (int)All.Nearest );
GLESConfig.GlCheckError( this );
OpenGL.TexParameter( All.Texture2D, All.TextureWrapS, (int)All.ClampToEdge );
GLESConfig.GlCheckError( this );
OpenGL.TexParameter( All.Texture2D, All.TextureWrapT, (int)All.ClampToEdge );
GLESConfig.GlCheckError( this );
// If we can do automip generation and the user desires this, do so
MipmapsHardwareGenerated = Root.Instance.RenderSystem.HardwareCapabilities.HasCapability( Capabilities.HardwareMipMaps ) && !PixelUtil.IsCompressed( Format );
if ( ( Usage & TextureUsage.AutoMipMap ) == TextureUsage.AutoMipMap && RequestedMipmapCount > 0 && MipmapsHardwareGenerated )
{
OpenGL.TexParameter( All.Texture2D, All.GenerateMipmap, (int)All.True );
GLESConfig.GlCheckError( this );
}
// Allocate internal buffer so that TexSubImageXD can be used
// Internal format
All format = GLESPixelUtil.GetClosestGLInternalFormat( Format, HardwareGammaEnabled );
int width = Width;
int height = Height;
int depth = Depth;
if ( PixelUtil.IsCompressed( Format ) )
{
// Compressed formats
int size = PixelUtil.GetMemorySize( Width, Height, Depth, Format );
// Provide temporary buffer filled with zeroes as glCompressedTexImageXD does not
// accept a 0 pointer like normal glTexImageXD
// Run through this process for every mipmap to pregenerate mipmap pyramid
byte[] tmpData = new byte[ size ];
IntPtr tmpDataptr = Memory.PinObject( tmpData );
for ( int mip = 0; mip <= MipmapCount; mip++ )
{
size = PixelUtil.GetMemorySize( Width, Height, Depth, Format );
OpenGL.CompressedTexImage2D( All.Texture2D, mip, format, width, height, 0, size, tmpDataptr );
GLESConfig.GlCheckError( this );
if ( width > 1 )
{
width = width / 2;
}
if ( height > 1 )
{
height = height / 2;
}
if ( depth > 1 )
{
depth = depth / 2;
}
}
Memory.UnpinObject( tmpData );
}
else
{
// Run through this process to pregenerate mipmap pyramid
for ( int mip = 0; mip <= MipmapCount; mip++ )
{
OpenGL.TexImage2D( All.Texture2D, mip, (int)format, width, height, 0, format, All.UnsignedByte, IntPtr.Zero );
GLESConfig.GlCheckError( this );
if ( width > 1 )
{
width = width / 2;
}
if ( height > 1 )
{
height = height / 2;
}
}
}
CreateSurfaceList();
// Get final internal format
Format = GetBuffer( 0, 0 ).Format;
}