internal String Compile( bool autoManageTextureUnits )
{
StringBuilder compileErrors = new StringBuilder();
// assume not supported unless it proves otherwise
_isSupported = false;
// grab a ref to the current hardware caps
RenderSystemCapabilities caps = Root.Instance.RenderSystem.Capabilities;
int numAvailTexUnits = caps.TextureUnitCount;
int passNum = 0;
for ( int i = 0; i < _passes.Count; i++, passNum++ )
{
Pass currPass = _passes[ i ];
// Adjust pass index
currPass.Index = passNum;
// Check for advanced blending operation support
#warning Capabilities.AdvancedBlendOperation implementation required
//if ( ( currPass.SceneBlendingOperation != SceneBlendingOperation.Add || currPass.SceneBlendingOperationAlpha != SceneBlendingOperation.Add ) &&
// !caps.HasCapability( Capabilities.AdvancedBlendOperations ) )
//{
// return false;
//}
// Check texture unit requirements
int numTexUnitsRequired = currPass.TextureUnitStageCount;
// Don't trust getNumTextureUnits for programmable
if ( !currPass.HasFragmentProgram )
{
if ( numTexUnitsRequired > numAvailTexUnits )
{
if ( !autoManageTextureUnits )
{
// The user disabled auto pass split
compileErrors.AppendFormat( "Pass {0}: Too many texture units for the current hardware and no splitting allowed.", i );
}
else if ( currPass.HasVertexProgram )
{
// Can't do this one, and can't split a programmable pass
compileErrors.AppendFormat( "Pass {0}: Too many texture units for the current hardware and cannot split programmable passes.", i );
}
}
}
// if this has a vertex program, check the syntax code to be sure the hardware supports it
if ( currPass.HasVertexProgram )
{
// check vertex program version
if ( !currPass.VertexProgram.IsSupported )
{
// can't do this one
compileErrors.AppendFormat( "Pass {0}: Fragment Program {1} cannot be used - {2}",
i,
currPass.VertexProgramName,
currPass.VertexProgram.HasCompileError ? "Compile Error." : "Not Supported." );
}
}
if ( currPass.HasGeometryProgram )
{
// check fragment program version
if ( !currPass.GeometryProgram.IsSupported )
{
// can't do this one
compileErrors.AppendFormat( "Pass {0}: Geometry Program {1} cannot be used - {2}",
i,
currPass.GeometryProgramName,
currPass.GeometryProgram.HasCompileError ? "Compile Error." : "Not Supported." );
}
}
else
{
// check support for a few fixed function options while we are here
for ( int j = 0; j < currPass.TextureUnitStageCount; j++ )
{
TextureUnitState texUnit = currPass.GetTextureUnitState( j );
// check to make sure we have some cube mapping support
if ( texUnit.Is3D && !caps.HasCapability( Capabilities.CubeMapping ) )
{
compileErrors.AppendFormat( "Pass {0} Tex {1} : Cube maps not supported by current environment.", i, j );
}
// if this is a Dot3 blending layer, make sure we can support it
if ( texUnit.ColorBlendMode.operation == LayerBlendOperationEx.DotProduct && !caps.HasCapability( Capabilities.Dot3 ) )
{
compileErrors.AppendFormat( "Pass {0} Tex {1} : Volume textures not supported by current environment.", i, j );
}
}
// keep splitting until the texture units required for this pass are available
while ( numTexUnitsRequired > numAvailTexUnits )
{
// split this pass up into more passes
currPass = currPass.Split( numAvailTexUnits );
numTexUnitsRequired = currPass.TextureUnitStageCount;
}
}
}
// if we made it this far, we are good to go!
_isSupported = true;
// Compile for categorized illumination on demand
ClearIlluminationPasses();
_illuminationPassesCompilationPhase = IlluminationPassesCompilationPhase.NotCompiled;
return compileErrors.ToString();
}