public void CreateResources( bool forResizeOnly )
{
// Create temporary textures
// In principle, temporary textures could be shared between multiple viewports
// (CompositorChains). This will save a lot of memory in case more viewports
// are composited.
List<Texture> assignedTextures = new List<Texture>();
foreach ( CompositionTechnique.TextureDefinition def in technique.TextureDefinitions )
{
//This is a reference, isn't created in this compositor
if ( !string.IsNullOrEmpty( def.ReferenceCompositorName ) )
{
continue;
}
//This is a global texture, just link the created resources from the parent
if ( def.Scope == CompositionTechnique.TextureScope.Global )
{
Compositor parentComp = technique.Parent;
if ( def.PixelFormats.Count > 1 )
{
int atch = 0;
foreach ( Axiom.Media.PixelFormat p in def.PixelFormats )
{
Texture tex = parentComp.GetTextureInstance( def.Name, atch++ );
localTextures.Add( GetMrtTextureLocalName( def.Name, atch ), tex );
}
MultiRenderTarget mrt = (MultiRenderTarget)parentComp.GetRenderTarget( def.Name );
localMrts.Add( def.Name, mrt );
}
else
{
Texture tex = parentComp.GetTextureInstance( def.Name, 0 );
localTextures.Add( def.Name, tex );
}
continue;
}
// Determine width and height
int width = def.Width;
int height = def.Height;
int fsaa;
string fsaahint;
bool hwGamma;
// Skip this one if we're only (re)creating for a resize & it's not derived
// from the target size
if ( forResizeOnly && width != 0 && height != 0 )
{
continue;
}
DeriveTextureRenderTargetOptions( def.Name, out hwGamma, out fsaa, out fsaahint );
if ( width == 0 )
{
width = (int)( chain.Viewport.ActualWidth * def.WidthFactor );
}
if ( height == 0 )
{
height = (int)( chain.Viewport.ActualHeight * def.HeightFactor );
}
// determine options as a combination of selected options and possible options
if ( !def.Fsaa )
{
fsaa = 0;
fsaahint = string.Empty;
}
hwGamma = hwGamma || def.HwGammaWrite;
// Make the tetxure
RenderTarget rendTarget;
if ( def.PixelFormats.Count > 1 )
{
string mrtBaseName = "c" + resourceDummyCounter++ + "/" + def.Name + "/" + chain.Viewport.Target.Name;
MultiRenderTarget mrt =
Root.Instance.RenderSystem.CreateMultiRenderTarget( mrtBaseName );
localMrts.Add( mrtBaseName, mrt );
// create and bind individual surfaces
int atch = 0;
foreach ( Axiom.Media.PixelFormat p in def.PixelFormats )
{
string texName = mrtBaseName + "/" + atch;
string mrtLocalName = GetMrtTextureLocalName( def.Name, atch );
Texture tex;
if ( def.Pooled )
{
// get / create pooled texture
tex = CompositorManager.Instance.GetPooledTexture( texName, mrtLocalName, width, height, p, fsaa, fsaahint, hwGamma && !PixelUtil.IsFloatingPoint( p ),
assignedTextures, this, def.Scope );
}
else
{
tex = TextureManager.Instance.CreateManual( texName, ResourceGroupManager.InternalResourceGroupName, TextureType.TwoD, width, height, 0, p, TextureUsage.RenderTarget, null, hwGamma && !PixelUtil.IsFloatingPoint( p ), fsaa, fsaahint );
}
RenderTexture rt = tex.GetBuffer().GetRenderTarget();
rt.IsAutoUpdated = false;
mrt.BindSurface( atch++, rt );
// Also add to local textures so we can look up
localTextures.Add( mrtLocalName, tex );
}
rendTarget = mrt;
}
else
{
string texName = "c" + resourceDummyCounter++ + "/" + def.Name + "/" + chain.Viewport.Target.Name;
// spaces in the name can cause plugin problems.
// this is an auto generated name - so no spaces can't hurt us.
texName = texName.Replace( ' ', '_' );
Texture tex;
if ( def.Pooled )
{
// get / create pooled texture
tex = CompositorManager.Instance.GetPooledTexture( texName, def.Name, width, height, def.PixelFormats[ 0 ], fsaa, fsaahint, hwGamma && !PixelUtil.IsFloatingPoint( def.PixelFormats[ 0 ] ),
assignedTextures, this, def.Scope );
}
else
{
tex = TextureManager.Instance.CreateManual( texName, ResourceGroupManager.InternalResourceGroupName, TextureType.TwoD, width, height, 0, def.PixelFormats[ 0 ], TextureUsage.RenderTarget, null, hwGamma && !PixelUtil.IsFloatingPoint( def.PixelFormats[ 0 ] ), fsaa, fsaahint );
}
rendTarget = tex.GetBuffer().GetRenderTarget();
localTextures.Add( def.Name, tex );
}
//Set DepthBuffer pool for sharing
rendTarget.DepthBufferPool = def.DepthBufferId;
// Set up viewport over entire texture
rendTarget.IsAutoUpdated = false;
// We may be sharing / reusing this texture, so test before adding viewport
if ( rendTarget.NumViewports == 0 )
{
Camera camera = chain.Viewport.Camera;
// Save last viewport and current aspect ratio
Viewport oldViewport = camera.Viewport;
float aspectRatio = camera.AspectRatio;
Viewport v = rendTarget.AddViewport( camera );
v.SetClearEveryFrame( false );
v.ShowOverlays = false;
v.BackgroundColor = new ColorEx( 0, 0, 0, 0 );
// Should restore aspect ratio, in case of auto aspect ratio
// enabled, it'll changed when add new viewport.
camera.AspectRatio = aspectRatio;
// Should restore last viewport, i.e. never disturb user code
// which might based on that.
camera.NotifyViewport( oldViewport );
}
}
OnResourceCreated( new CompositorInstanceResourceEventArgs( forResizeOnly ) );
}