protected internal virtual void CreateShadowTextures( ushort size, ushort count, PixelFormat format )
{
string baseName = "Axiom/ShadowTexture";
if ( !this.IsShadowTechniqueTextureBased ||
this.shadowTextures.Count > 0 &&
count == this.shadowTextureCount &&
size == this.shadowTextureSize &&
format == this.shadowTextureFormat )
{
// no change
return;
}
// destroy existing
this.DestroyShadowTextures();
// Recreate shadow textures
for ( ushort t = 0; t < count; ++t )
{
string targName = string.Format( "{0}{1}", baseName, t );
string matName = string.Format( "{0}Mat{1}", baseName, t );
string camName = string.Format( "{0}Cam{1}", baseName, t );
// try to get existing texture first, since we share these between
// potentially multiple SMs
Texture shadowTex = (Texture)TextureManager.Instance[ targName ];
if ( shadowTex == null )
{
shadowTex = TextureManager.Instance.CreateManual( targName,
ResourceGroupManager.InternalResourceGroupName,
TextureType.TwoD,
size,
size,
0,
format,
TextureUsage.RenderTarget );
}
else if ( shadowTex.Width != size ||
shadowTex.Height != size ||
shadowTex.Format != format )
{
LogManager.Instance.Write( "Warning: shadow texture #{0} is shared " +
"between scene managers but the sizes / formats " +
"do not agree. Consider rationalizing your scene manager " +
"shadow texture settings.",
t );
}
shadowTex.Load();
RenderTexture shadowRTT = shadowTex.GetBuffer().GetRenderTarget();
// Create camera for this texture, but note that we have to rebind
// in prepareShadowTextures to coexist with multiple SMs
Camera cam = this.CreateCamera( camName );
cam.AspectRatio = 1.0f;
// Don't use rendering distance for light cameras; we don't want shadows
// for visible objects disappearing, especially for directional lights
cam.UseRenderingDistance = false;
this.shadowTextureCameras.Add( cam );
// Create a viewport, if not there already
if ( shadowRTT.NumViewports == 0 )
{
// Note camera assignment is transient when multiple SMs
Viewport view = shadowRTT.AddViewport( cam );
view.SetClearEveryFrame(true);
// remove overlays
view.ShowOverlays = false;
}
// Don't update automatically - we'll do it when required
shadowRTT.IsAutoUpdated = false;
this.shadowTextures.Add( shadowTex );
// Also create corresponding Material used for rendering this shadow
Material mat = (Material)MaterialManager.Instance[ matName ];
if ( mat == null )
{
mat = (Material)MaterialManager.Instance.Create( matName, ResourceGroupManager.InternalResourceGroupName );
}
// create texture unit referring to render target texture
TextureUnitState texUnit = mat.GetTechnique( 0 ).GetPass( 0 ).CreateTextureUnitState( targName );
// set projective based on camera
texUnit.SetProjectiveTexturing( true, cam );
texUnit.SetTextureAddressingMode( TextureAddressing.Border );
texUnit.TextureBorderColor = ColorEx.White;
mat.Touch();
}
}