Struct for holding the script context while parsing.
예제 #1
0
		protected static bool ParseBindingType( string parameters, MaterialScriptContext context )
		{
			switch ( parameters.ToLower() )
			{
				case "texture":
					context.textureUnit.BindingType = TextureBindingType.Fragment;
					break;
				case "vertex":
					context.textureUnit.BindingType = TextureBindingType.Vertex;
					break;
				default:
					LogParseError( context, "Invalid binding type option - {0}", parameters );
					break;
			}
			return false;
		}
예제 #2
0
		protected static bool ParseAmbient( string parameters, MaterialScriptContext context )
		{
			string[] values = parameters.Split( new char[] { ' ', '\t' } );

			// must be 1, 3 or 4 parameters
			if ( values.Length == 1 )
			{
				if ( values[ 0 ].ToLower() == "vertexcolour" ||
					 values[ 0 ].ToLower() == "vertexcolor" )
				{
					context.pass.VertexColorTracking |= TrackVertexColor.Ambient;
				}
				else
				{
					LogParseError( context, "Bad ambient attribute, single parameter flag must be 'vertexcolour' or 'vertexcolor'." );
				}
			}
			else if ( values.Length == 3 || values.Length == 4 )
			{
				context.pass.Ambient = StringConverter.ParseColor( values );
				context.pass.VertexColorTracking &= ~TrackVertexColor.Ambient;
			}
			else
			{
				LogParseError( context, "Bad ambient attribute, wrong number of parameters (expected 1, 3 or 4)." );
			}

			return false;
		}
예제 #3
0
		protected static bool ParseCullSoftware( string parameters, MaterialScriptContext context )
		{
			// lookup the real enum equivalent to the script value
			object val = ScriptEnumAttribute.Lookup( parameters, typeof( ManualCullingMode ) );

			// if a value was found, assign it
			if ( val != null )
			{
				context.pass.ManualCullingMode = (ManualCullingMode)val;
			}
			else
			{
				string legalValues = ScriptEnumAttribute.GetLegalValues( typeof( ManualCullingMode ) );
				LogParseError( context, "Bad cull_software attribute, valid parameters are {0}.", legalValues );
			}

			return false;
		}
예제 #4
0
		protected static bool ParseLodDistances( string parameters, MaterialScriptContext context )
		{
			context.material.LodStrategy = LodStrategyManager.Instance.GetStrategy( DistanceLodStrategy.StrategyName );

			string[] values = parameters.Split( new char[] { ' ', '\t' } );

			LodValueList lodDistances = new LodValueList();

			for ( int i = 0; i < values.Length; i++ )
			{
				lodDistances.Add( StringConverter.ParseFloat( values[ i ] ) );
			}

			context.material.SetLodLevels( lodDistances );

			return false;
		}
예제 #5
0
		protected static bool ParseLodIndex( string parameters, MaterialScriptContext context )
		{
			context.technique.LodIndex = int.Parse( parameters );

			return false;
		}
예제 #6
0
		protected static bool ParseTextureUnit( string parameters, MaterialScriptContext context )
		{
			// create a new texture unit
			context.textureUnit = context.pass.CreateTextureUnitState();

			// get the texture unit name
			string[] values = parameters.Split( new char[] { ' ', '\t' } );
			if ( values.Length > 0 && values[ 0 ].Length > 0 )
				context.textureUnit.Name = values[ 0 ];

			// update section
			context.section = MaterialScriptSection.TextureUnit;

			// increase texture unit level depth
			context.stateLev++;

			// return true because this must be followed by a {
			return true;
		}
예제 #7
0
		protected static bool ParseSetTextureAlias( string parameters, MaterialScriptContext context )
		{
			// get the texture alias
			string[] values = parameters.Split( new char[] { ' ', '\t' } );

			if ( values.Length != 2 )
			{
				LogParseError( context, "Invalid set_texture_alias entry - expected 2 parameters." );
				return true;
			}
			// update section
			if ( context.textureAliases.ContainsKey( values[ 0 ] ) )
			{
				context.textureAliases[ values[ 0 ] ] = values[ 1 ];
			}
			else
			{
				context.textureAliases.Add( values[ 0 ], values[ 1 ] );
			}

			return false;
		}
예제 #8
0
		protected static bool ParseProgramMorphAnimation( string parameters, MaterialScriptContext context )
		{
			context.programDef.supportsMorphAnimation = bool.Parse( parameters );

			return false;
		}
예제 #9
0
		protected static bool ParseProgramPoseAnimation( string parameters, MaterialScriptContext context )
		{
			context.programDef.poseAnimationCount = ushort.Parse( parameters );

			return false;
		}
예제 #10
0
		protected static bool ParseProgramSource( string parameters, MaterialScriptContext context )
		{
			// source filename, preserve case
			context.programDef.source = parameters;

			return false;
		}
예제 #11
0
		protected static bool ParseProgramSyntax( string parameters, MaterialScriptContext context )
		{
			context.programDef.syntax = parameters.ToLower();

			return false;
		}
예제 #12
0
		protected static bool ParseParamNamedAuto( string parameters, MaterialScriptContext context )
		{
			// skip this if the program is not supported or could not be found
			if ( context.program == null || !context.program.IsSupported )
			{
				return false;
			}

			string[] values = parameters.Split( new char[] { ' ', '\t' } );

			if ( values.Length != 2 && values.Length != 3 )
			{
				LogParseError( context, "Invalid param_named_auto attribute - expected 2 or 3 parameters." );
				return false;
			}

			// get start index
			try
			{
				int index = context.programParams.GetParamIndex( values[ 0 ] );

				ProcessAutoProgramParam( index, "param_named_auto", values, context );
			}
			catch ( Exception ex )
			{
				LogParseError( context, "Invalid param_named_auto attribute - {0}.", ex.Message );
				return false;
			}

			return false;
		}
예제 #13
0
		protected static bool ParseParamIndexedAuto( string parameters, MaterialScriptContext context )
		{
			// skip this if the program is not supported or could not be found
			if ( context.program == null || !context.program.IsSupported )
			{
				return false;
			}

			string[] values = parameters.Split( new char[] { ' ', '\t' } );

			if ( values.Length != 2 && values.Length != 3 )
			{
				LogParseError( context, "Invalid param_indexed_auto attribute - expected at 2 or 3 parameters." );
				return false;
			}

			// get start index
			int index = int.Parse( values[ 0 ] );

			ProcessAutoProgramParam( index, "param_indexed_auto", values, context );

			return false;
		}
예제 #14
0
		protected static bool ParseWaveXForm( string parameters, MaterialScriptContext context )
		{
			string[] values = parameters.Split( new char[] { ' ', '\t' } );

			if ( values.Length != 6 )
			{
				LogParseError( context, "Bad wave_xform attribute, wrong number of parameters (expected 6)." );
				return false;
			}

			TextureTransform transType = 0;
			WaveformType waveType = 0;

			// check the transform type
			object val = ScriptEnumAttribute.Lookup( values[ 0 ], typeof( TextureTransform ) );

			if ( val == null )
			{
				string legalValues = ScriptEnumAttribute.GetLegalValues( typeof( TextureTransform ) );
				LogParseError( context, "Bad wave_xform attribute, valid transform type values are {0}.", legalValues );
				return false;
			}

			transType = (TextureTransform)val;

			// check the wavetype
			val = ScriptEnumAttribute.Lookup( values[ 1 ], typeof( WaveformType ) );

			if ( val == null )
			{
				string legalValues = ScriptEnumAttribute.GetLegalValues( typeof( WaveformType ) );
				LogParseError( context, "Bad wave_xform attribute, valid waveform type values are {0}.", legalValues );
				return false;

			}

			waveType = (WaveformType)val;

			// set the transform animation
			context.textureUnit.SetTransformAnimation(
				transType,
				waveType,
				StringConverter.ParseFloat( values[ 2 ] ),
				StringConverter.ParseFloat( values[ 3 ] ),
				StringConverter.ParseFloat( values[ 4 ] ),
				StringConverter.ParseFloat( values[ 5 ] ) );

			return false;
		}
예제 #15
0
		protected static bool ParseTechnique( string parameters, MaterialScriptContext context )
		{
			// create a new technique
			context.technique = context.material.CreateTechnique();

			// update section
			context.section = MaterialScriptSection.Technique;

			// increate technique level depth
			context.techLev++;

			// get the technique name
			string[] values = parameters.Split( new char[] { ' ', '\t' } );

			if ( values.Length > 0 && values[ 0 ].Length > 0 )
				context.technique.Name = values[ 0 ];

			// return true because this must be followed by a {
			return true;
		}
예제 #16
0
		protected static bool ParseDefaultParams( string parameters, MaterialScriptContext context )
		{
			context.section = MaterialScriptSection.DefaultParameters;

			// should be a brace next
			return true;
		}
예제 #17
0
		protected static bool ParsePass( string parameters, MaterialScriptContext context )
		{
			// get the pass name
			string[] values = parameters.Split( new char[] { ' ', '\t' } );

			// if params is not empty then see if the pass name already exists
			if ( values.Length > 0 && values[ 0 ].Length > 0 && context.technique.PassCount > 0 )
			{
				// find the pass with name = params
				Pass foundPass = context.technique.GetPass( values[ 0 ] );
				if ( foundPass != null )
					context.passLev = foundPass.Index;
				else
					// name was not found so a new pass is needed
					// position pass level to the end index
					// a new pass will be created later on
					context.passLev = context.technique.PassCount;
			}
			else
			{
				// increase the pass level depth;
				context.passLev++;
			}

			if ( context.technique.PassCount > context.passLev )
			{
				context.pass = context.technique.GetPass( context.passLev );
			}
			else
			{
				// create a new pass
				context.pass = context.technique.CreatePass();
				if ( values.Length > 0 && values[ 0 ].Length > 0 )
					context.pass.Name = values[ 0 ];
			}

			// update section
			context.section = MaterialScriptSection.Pass;

			// return true because this must be followed by a {
			return true;
		}
예제 #18
0
		/// <summary>
		///
		/// </summary>
		/// <param name="index"></param>
		/// <param name="commandName"></param>
		/// <param name="parameters"></param>
		/// <param name="context"></param>
		protected static void ProcessManualProgramParam( int index, string commandName, string[] parameters, MaterialScriptContext context )
		{
			// NB we assume that the first element of vecparams is taken up with either
			// the index or the parameter name, which we ignore

			int dims, roundedDims;
			bool isFloat = false;
			string type = parameters[ 1 ].ToLower();

			if ( type == "matrix4x4" )
			{
				dims = 16;
				isFloat = true;
			}
			else if ( type.IndexOf( "float" ) != -1 )
			{
				if ( type == "float" )
				{
					dims = 1;
				}
				else
				{
					// the first 5 letters are "float", get the dim indicator at the end
					// this handles entries like 'float4'
					dims = int.Parse( type.Substring( 5 ) );
				}

				isFloat = true;
			}
			else if ( type.IndexOf( "int" ) != -1 )
			{
				if ( type == "int" )
				{
					dims = 1;
				}
				else
				{
					// the first 5 letters are "int", get the dim indicator at the end
					dims = int.Parse( type.Substring( 3 ) );
				}
			}
			else
			{
				LogParseError( context, "Invalid {0} attribute - unrecognized parameter type {1}.", commandName, type );
				return;
			}

			// make sure we have enough params for this type's size
			if ( parameters.Length != 2 + dims )
			{
				LogParseError( context, "Invalid {0} attribute - you need {1} parameters for a parameter of type {2}", commandName, 2 + dims, type );
				return;
			}

			// Round dims to multiple of 4
			if ( dims % 4 != 0 )
			{
				roundedDims = dims + 4 - ( dims % 4 );
			}
			else
			{
				roundedDims = dims;
			}

			int i = 0;

			// now parse all the values
			if ( isFloat )
			{
				float[] buffer = new float[ roundedDims ];

				// do specified values
				for ( i = 0; i < dims; i++ )
				{
					buffer[ i ] = StringConverter.ParseFloat( parameters[ i + 2 ] );
				}

				// fill up to multiple of 4 with zero
				for ( ; i < roundedDims; i++ )
				{
					buffer[ i ] = 0.0f;
				}

				context.programParams.SetConstant( index, buffer );
			}
			else
			{
				int[] buffer = new int[ roundedDims ];

				// do specified values
				for ( i = 0; i < dims; i++ )
				{
					buffer[ i ] = int.Parse( parameters[ i + 2 ] );
				}

				// fill up to multiple of 4 with zero
				for ( ; i < roundedDims; i++ )
				{
					buffer[ i ] = 0;
				}

				context.programParams.SetConstant( index, buffer );
			}
		}
예제 #19
0
		protected static bool ParseTextureAlias( string parameters, MaterialScriptContext context )
		{
			Debug.Assert( context.textureUnit != null );

			// get the texture alias
			string[] values = parameters.Split( new char[] { ' ', '\t' } );

			if ( values.Length != 1 )
			{
				LogParseError( context, "Invalid texture_alias entry - expected 1 parameter." );
				return true;
			}
			// update section
			context.textureUnit.TextureNameAlias = values[ 0 ];

			return false;
		}
예제 #20
0
		/// <summary>
		///
		/// </summary>
		/// <param name="index"></param>
		/// <param name="commandName"></param>
		/// <param name="parameters"></param>
		/// <param name="context"></param>
		protected static void ProcessAutoProgramParam( int index, string commandName, string[] parameters, MaterialScriptContext context )
		{
			bool extras = false;

			object val = ScriptEnumAttribute.Lookup( parameters[ 1 ], typeof( GpuProgramParameters.AutoConstantType ) );

			if ( val != null )
			{
				bool isFloat = false;
				GpuProgramParameters.AutoConstantType constantType = (GpuProgramParameters.AutoConstantType)val;

				// these types require extra data
				if ( constantType == GpuProgramParameters.AutoConstantType.LightDiffuseColor ||
					constantType == GpuProgramParameters.AutoConstantType.LightSpecularColor ||
					constantType == GpuProgramParameters.AutoConstantType.LightAttenuation ||
					constantType == GpuProgramParameters.AutoConstantType.LightPosition ||
					constantType == GpuProgramParameters.AutoConstantType.LightDirection ||
					constantType == GpuProgramParameters.AutoConstantType.LightPositionObjectSpace ||
					constantType == GpuProgramParameters.AutoConstantType.LightDirectionObjectSpace ||
					constantType == GpuProgramParameters.AutoConstantType.Custom )
				{

					extras = true;
					isFloat = false;
				}
				else if ( constantType == GpuProgramParameters.AutoConstantType.Time_0_X ||
						   constantType == GpuProgramParameters.AutoConstantType.SinTime_0_X )
				{
					extras = true;
					isFloat = true;
				}


				// do we require extra data for this parameter?
				if ( extras )
				{
					if ( parameters.Length != 3 )
					{
						LogParseError( context, "Invalid {0} attribute - Expected 3 parameters.", commandName );
						return;
					}
				}
				if ( isFloat && extras )
					context.programParams.SetAutoConstant( index, constantType, float.Parse( parameters[ 2 ] ) );
				else if ( extras )
					context.programParams.SetAutoConstant( index, constantType, int.Parse( parameters[ 2 ] ) );
				else if ( constantType == GpuProgramParameters.AutoConstantType.Time )
				{
					if ( parameters.Length == 3 )
						context.programParams.SetAutoConstant( index, constantType, float.Parse( parameters[ 2 ] ) );
					else
						context.programParams.SetAutoConstant( index, constantType, 1.0f );
				}
				else
					context.programParams.SetAutoConstant( index, constantType, 0 );
			}
			else
			{
				string legalValues = ScriptEnumAttribute.GetLegalValues( typeof( GpuProgramParameters.AutoConstantType ) );
				LogParseError( context, "Bad auto gpu program param - Invalid param type '{0}', valid values are {1}.", parameters[ 1 ], legalValues );
				return;
			}
		}
예제 #21
0
		protected static bool ParseLodStrategy( string parameters, MaterialScriptContext context )
		{
			LodStrategy lodStrategy = LodStrategyManager.Instance.GetStrategy( parameters );

			if ( lodStrategy == null )
			{
				LogParseError( context, "Bad lod_strategy attribute, , available lod strategy name expected." );
			}

			context.material.LodStrategy = lodStrategy;

			return false;
		}
예제 #22
0
		/// <summary>
		///		Helper method for logging parser errors.
		/// </summary>
		/// <param name="context">Current parsing context.</param>
		/// <param name="error">Error message.</param>
		/// <param name="substitutions">Items to sub in for the error message, if the error contains them.</param>
		protected static void LogParseError( MaterialScriptContext context, string error, params object[] substitutions )
		{
			StringBuilder errorBuilder = new StringBuilder();

			// log material name only if filename not specified
			if ( context.filename == null && context.material != null )
			{
				errorBuilder.Append( "Error in material " );
				errorBuilder.Append( context.material.Name );
				errorBuilder.Append( " : " );
				errorBuilder.AppendFormat( error, substitutions );
			}
			else
			{
				if ( context.material != null )
				{
					errorBuilder.Append( "Error in material " );
					errorBuilder.Append( context.material.Name );
					errorBuilder.AppendFormat( " at line {0} ", context.lineNo );
					errorBuilder.AppendFormat( " of {0}: ", context.filename );
					errorBuilder.AppendFormat( error, substitutions );
				}
				else
				{
					errorBuilder.AppendFormat( "Error at line {0} ", context.lineNo );
					errorBuilder.AppendFormat( " of {0}: ", context.filename );
					errorBuilder.AppendFormat( error, substitutions );
				}
			}

			LogManager.Instance.Write( errorBuilder.ToString() );
		}
예제 #23
0
		protected static bool ParseTransparencyCastsShadows( string parameters, MaterialScriptContext context )
		{
			if ( parameters != "on" && parameters != "off" )
			{
				LogParseError( context, "Bad transparency_casts_shadows attribute, valid parameters are 'on' or 'off'." );
			}

			context.material.TransparencyCastsShadows = StringConverter.ParseBool( parameters );

			return false;
		}
예제 #24
0
		/// <summary>
		///		Parse custom GPU program parameters.
		/// </summary>
		/// <remarks>
		///		This one is called explicitly, and is not added to any parser list.
		/// </remarks>
		protected static bool ParseProgramCustomParameter( string parameters, MaterialScriptContext context )
		{
			// This params object does not have the command stripped
			// Lower case the command, but not the value incase it's relevant
			// Split only up to first delimiter, program deals with the rest
			string[] values = StringConverter.Split( parameters, new char[] { ' ', '\t' }, 2 );

			if ( values.Length != 2 )
			{
				LogParseError( context, "Invalid custom program parameter entry; there must be a parameter name and at least one value." );
				return false;
			}

			context.programDef.customParameters.Add( new KeyValuePair<string, string>( values[ 0 ], values[ 1 ] ) );

			return false;
		}
예제 #25
0
		protected static bool ParseScheme( string parameters, MaterialScriptContext context )
		{
			context.technique.SchemeName = parameters;
			return false;
		}
예제 #26
0
		protected static bool ParseMaterial( string parameters, MaterialScriptContext context )
		{
			// check params for reference to parent material to copy from
			// syntax: material name : parentMaterialName
			// check params for a colon after the first name and extract the parent name
			string[] values = parameters.Split( new char[] { ':' } );
			Material basematerial = null;

			// create a brand new material
			if ( values.Length >= 2 )
			{
				// if a second parameter exists then assume its the name of the base material
				// that this new material should clone from
				values[ 1 ] = values[ 1 ].Trim();
				// make sure base material exists
				basematerial = (Material)MaterialManager.Instance.GetByName( values[ 1 ] );
				// if it doesn't exist then report error in log and just create a new material
				if ( basematerial == null )
				{
					LogParseError( context, "parent material:" + values[ 1 ] + " not found for new material:" + values[ 0 ] );
				}
			}

			string materialName = values[ 0 ].Trim();
			context.material = (Material)MaterialManager.Instance.Create( materialName, context.groupName );
			if ( basematerial != null )
			{
				// copy parent material details to new material
				basematerial.CopyTo( context.material, false );
			}
			else
			{
				// remove pre-created technique from defaults
				context.material.RemoveAllTechniques();
			}

			context.material.Origin = context.filename;

			// update section
			context.section = MaterialScriptSection.Material;

			// return true because this must be followed by a {
			return true;
		}
예제 #27
0
		protected static bool ParseColorWrite( string parameters, MaterialScriptContext context )
		{
			switch ( parameters.ToLower() )
			{
				case "on":
					context.pass.ColorWriteEnabled = true;
					break;
				case "off":
					context.pass.ColorWriteEnabled = false;
					break;
				default:
					LogParseError( context, "Bad color_write attribute, valid parameters are 'on' or 'off'." );
					break;
			}

			return false;
		}
예제 #28
0
		protected static bool ParseFragmentProgram( string parameters, MaterialScriptContext context )
		{
			// update section
			context.section = MaterialScriptSection.Program;

			// create new program definition-in-progress
			context.programDef = new MaterialScriptProgramDefinition();
			context.programDef.progType = GpuProgramType.Fragment;
			context.programDef.supportsSkeletalAnimation = false;
			context.programDef.supportsMorphAnimation = false;
			context.programDef.poseAnimationCount = 0;

			// get name and language code
			string[] values = parameters.Split( new char[] { ' ', '\t' } );

			if ( values.Length != 2 )
			{
				LogParseError( context, "Invalid fragment_program entry - expected 2 parameters." );
				return true;
			}

			// name, preserve case
			context.programDef.name = values[ 0 ];
			// language code, make lower case
			context.programDef.language = values[ 1 ].ToLower();

			// return true, because this must be followed by a {
			return true;
		}
예제 #29
0
		protected static bool ParseDepthBias( string parameters, MaterialScriptContext context )
		{
			string[] values = parameters.Split( new char[] { ' ', '\t' } );

			float constantBias = float.Parse( values[ 0 ] );
			float slopeScaleBias = 0.0f;
			if ( values.Length > 1 )
			{
				slopeScaleBias = float.Parse( values[ 1 ] );
			}

			context.pass.SetDepthBias( constantBias, slopeScaleBias );

			return false;
		}
예제 #30
0
		protected static bool ParseTexture( string parameters, MaterialScriptContext context )
		{
			string[] values = parameters.Split( new char[] { ' ', '\t' } );

			if ( values.Length > 5 )
			{
				LogParseError( context, "Invalid texture attribute - expecting 5 parameters or less." );
				return false;
			}

			// use 2d as default if anything goes wrong
			TextureType texType = TextureType.TwoD;
			int mipmaps = (int)TextureMipmap.Default; // When passed to TextureManager::load, this means default to default number of mipmaps
			bool isAlpha = false;
			bool hwGamma = false;
			PixelFormat desiredFormat = PixelFormat.Unknown;

			for ( int p = 1; p < values.Length; p++ )
			{

				switch ( values[ p ].ToLower() )
				{
					case "1d":
						texType = TextureType.OneD;
						break;
					case "2d":
						texType = TextureType.TwoD;
						break;
					case "3d":
						texType = TextureType.ThreeD;
						break;
					case "cubic":
						texType = TextureType.CubeMap;
						break;
					case "unlimited":
						mipmaps = (int)TextureMipmap.Unlimited;
						break;
					case "alpha":
						isAlpha = true;
						break;
					case "gamma":
						hwGamma = true;
						break;
					default:
						int num;

						if ( StringConverter.ParseInt( values[ p ], out num ) )
						{
							mipmaps = num;
						}
						else if ( ( desiredFormat = PixelUtil.GetFormatFromName( values[ p ], true, false ) ) != PixelFormat.Unknown )
						{
							// Nothing to do here.
						}
						else
						{
							LogParseError( context, "Invalid texture option - " + values[ p ] + "." );
						}
						break;
				}
			}

			context.textureUnit.SetTextureName( values[ 0 ], texType );
			context.textureUnit.MipmapCount = mipmaps;
			context.textureUnit.IsAlpha = isAlpha;
			context.textureUnit.DesiredFormat = desiredFormat;
			context.textureUnit.IsHardwareGammaEnabled = hwGamma;

			return false;
		}