private void Parse( string _block ) { m_states.m_unknownStates.Clear(); m_parms.m_unknownParms.Clear(); m_options.m_unknownOptions.Clear(); m_unknownVariables.Clear(); m_forbiddenParms.Clear(); m_isUsingVegetationParms = false; m_isUsingCloudParms = false; m_isUsingWaterParms = false; Parser P = new Parser( _block ); while ( P.OK ) { string token = P.ReadString(); if ( token == null ) break; // Done! if ( token.StartsWith( "//" ) ) { RecordSingleLineCommentVariable( token, P ); continue; } if ( token.StartsWith( "/*" ) ) { RecordCommentVariable( token, P ); continue; } if ( token.EndsWith( "{" ) ) { // Handle problematic parms without space before their values token = token.Substring( 0, token.Length-1 ); P.m_Index--; } P.SkipSpaces(); switch ( token.ToLower() ) { case "version": P.SkipSpaces(); m_version = P.ReadInteger(); break; case "state": m_states.Parse( P.ReadBlock() ); break; case "parms": m_parms.Parse( P.ReadBlock() ); break; case "options": ParseOptions( P.ReadBlock() ); break; // Programs case "mainprogram": m_programs.SetMainProgram( P.ReadString() ); break; case "zprepassprogram": m_programs.m_ZPrepass = P.ReadString(); break; case "shadowprogram": m_programs.m_shadow = P.ReadString(); break; // Textures // Layer 0 case "diffusemap": Layer0.m_diffuse = new Layer.Texture( P.ReadToEOL() ); break; case "bumpmap": Layer0.m_normal = new Layer.Texture( P.ReadToEOL() ); break; case "glossmap": Layer0.m_gloss = new Layer.Texture( P.ReadToEOL() ); break; case "metallicmap": Layer0.m_metal = new Layer.Texture( P.ReadToEOL() ); break; case "specularmap": Layer0.m_specular = new Layer.Texture( P.ReadToEOL() ); break; case "heightmap": m_height = new Layer.Texture( P.ReadToEOL() ); break; case "lightmap": m_lightMap = new Layer.Texture( P.ReadToEOL() ); break; case "occlusionmap": Layer0.m_AO = new Layer.Texture( P.ReadToEOL() ); break; case "translucencymap": Layer0.m_translucency = new Layer.Texture( P.ReadToEOL() ); break; case "emissivemap": Layer0.m_emissive = new Layer.Texture( P.ReadToEOL() ); break; case "layer0_maskmap": Layer0.m_mask = new Layer.Texture( P.ReadToEOL() ); break; case "layer0_scalebias": Layer0.ParseScaleBias( P ); break; case "layer0_maskscalebias":Layer0.ParseMaskScaleBias( P ); break; case "layer0_colorconstant":Layer0.m_colorConstant = P.ReadFloat4(); break; // Layer 1 case "layer1_diffusemap": Layer1.m_diffuse = new Layer.Texture( P.ReadToEOL() ); break; case "layer1_bumpmap": Layer1.m_normal = new Layer.Texture( P.ReadToEOL() ); break; case "layer1_glossmap": Layer1.m_gloss = new Layer.Texture( P.ReadToEOL() ); break; case "layer1_specularmap": Layer1.m_specular = new Layer.Texture( P.ReadToEOL() ); break; case "layer1_metallicmap": Layer1.m_metal = new Layer.Texture( P.ReadToEOL() ); break; case "layer1_maskmap": Layer1.m_mask = new Layer.Texture( P.ReadToEOL() ); break; case "layer1_emissivemap": throw new Exception( "Shouldn't be allowed!" );//P.SkipSpaces(); Layer1.m_emissive = new Layer.Texture( P.ReadToEOL() ); break; case "layer1_scalebias": Layer1.ParseScaleBias( P ); break; case "layer1_maskscalebias":Layer1.ParseMaskScaleBias( P ); break; case "layer1_colorconstant":Layer1.m_colorConstant = P.ReadFloat4(); break; // Layer 2 case "layer2_diffusemap": Layer2.m_diffuse = new Layer.Texture( P.ReadToEOL() ); break; case "layer2_bumpmap": Layer2.m_normal = new Layer.Texture( P.ReadToEOL() ); break; case "layer2_glossmap": Layer2.m_gloss = new Layer.Texture( P.ReadToEOL() ); break; case "layer2_specularmap": Layer2.m_specular = new Layer.Texture( P.ReadToEOL() ); break; case "layer2_metallicmap": Layer2.m_metal = new Layer.Texture( P.ReadToEOL() ); break; case "layer2_emissivemap": throw new Exception( "Shouldn't be allowed!" );//P.SkipSpaces(); Layer2.m_emissive = new Layer.Texture( P.ReadToEOL() ); break; case "layer2_maskmap": Layer2.m_mask = new Layer.Texture( P.ReadToEOL() ); break; case "layer2_scalebias": Layer2.ParseScaleBias( P ); break; case "layer2_maskscalebias":Layer2.ParseMaskScaleBias( P ); break; case "layer2_colorconstant":Layer2.m_colorConstant = P.ReadFloat4(); break; // Main variables case "m_physicsmaterial": m_physicsMaterial = P.ReadToEOL(); break; case "wardroughness": float4 roughness = P.ReadFloat4(); m_glossMinMax.x = roughness.x; m_glossMinMax.y = roughness.y; break; case "metallicminmax": float4 metal = P.ReadFloat4(); m_metallicMinMax.x = metal.x; m_metallicMinMax.y = metal.y; break; default: if ( CheckSafeTokens( token ) ) RecordUnknownVariable( token, P ); else RecordForbiddenVariable( token, P ); break; } } }
static void RecordCommentVariable( List< string > _variables, string _token, Parser P ) { string comment = _token + P.SkipComment(); _variables.Add( comment ); }
static void RecordSingleLineCommentVariable( List< string > _variables, string _token, Parser P ) { string record = _token + P.ReadToEOL(); _variables.Add( record ); }
public void Parse( string _parms ) { m_rawBlendState = null; m_blendState = BLEND_STATE.OPAQUE; Parser P = new Parser( _parms ); while ( P.OK ) { string token = P.ReadString(); if ( token == null ) break; // Done! if ( token.StartsWith( "//" ) ) { RecordSingleLineCommentVariable( m_unknownStates, token, P ); continue; } if ( token.StartsWith( "/*" ) ) { RecordCommentVariable( m_unknownStates, token, P ); continue; } if ( token.EndsWith( "{" ) ) { // Handle problematic parms without space before their values token = token.Substring( 0, token.Length-1 ); P.m_Index--; } P.SkipSpaces(); switch ( token.ToLower() ) { case "blend": { P.SkipSpaces(); m_rawBlendState = P.ReadToEOL(); ParseBlendState( m_rawBlendState ); break; } default: m_unknownStates.Add( token + " " + P.ReadToEOL() ); break; } } }
void ParseBlendState( string _rawBlendState ) { m_blendState = BLEND_STATE.OPAQUE; Parser P = new Parser( _rawBlendState ); string sourceOp = P.ReadString(); string destOp = P.OK ? P.ReadString() : null; string[] ops = new string[] { sourceOp, destOp }; foreach ( string op in ops ) { if ( op != null ) switch ( op.ToUpper() ) { case "SRC_ALPHA": case "ONE_MINUS_SRC_ALPHA": case "DST_ALPHA": case "ONE_MINUS_DST_ALPHA": m_blendState = BLEND_STATE.ALPHA; break; } } }
public Texture( string _textureLine ) { m_rawTextureLine = _textureLine; // Parse texture name Parser P = new Parser( _textureLine ); m_name = P.ReadString( true, false ); try { // Check if it's a constant color m_name = m_name.ToLower(); if ( m_name.StartsWith( "_" ) ) { // Procedural texture switch ( m_name ) { case "_default": m_constantColorType = CONSTANT_COLOR_TYPE.DEFAULT; break; case "_black": m_constantColorType = CONSTANT_COLOR_TYPE.BLACK; break; case "_blackalphawhite": m_constantColorType = CONSTANT_COLOR_TYPE.BLACK_ALPHA_WHITE; break; case "_white": m_constantColorType = CONSTANT_COLOR_TYPE.WHITE; break; case "_invalid": m_constantColorType = CONSTANT_COLOR_TYPE.INVALID; break; default: throw new Exception( "Unsupported procedural texture type \"" + m_name + "\"!" ); } } else if ( m_name.StartsWith( "ipr_constantcolor" ) ) { m_constantColorType = CONSTANT_COLOR_TYPE.CUSTOM; P = new Parser( _textureLine ); P.ConsumeString( "ipr_constantColor", false ); string strColor = P.ReadBlock( '(', ')' ); m_customConstantColor = P.ReadFloat4( strColor ); // Compare known colors to revert to basic types if ( CompareFloat4( m_customConstantColor, float4.Zero ) ) { m_constantColorType = CONSTANT_COLOR_TYPE.BLACK; } else if ( CompareFloat4( m_customConstantColor, float4.UnitW ) ) { m_constantColorType = CONSTANT_COLOR_TYPE.BLACK_ALPHA_WHITE; } else if ( CompareFloat4( m_customConstantColor, float4.One ) ) { m_constantColorType = CONSTANT_COLOR_TYPE.WHITE; } } if ( m_constantColorType == CONSTANT_COLOR_TYPE.TEXTURE ) { // Build file name string fullPath = Path.Combine( ms_TexturesBasePath.FullName, m_name ); if ( Path.GetExtension( fullPath.ToLower() ) == "" ) fullPath += ".tga"; // Assume tga files if unspecified m_fileName = new FileInfo( fullPath ); } } catch ( Exception _e ) { m_error = _e; } }
public void Parse( string _parms ) { m_sortStage = SORT_STAGE.UNKNOWN; Parser P = new Parser( _parms ); while ( P.OK ) { string token = P.ReadString(); if ( token == null ) break; // Done! if ( token.StartsWith( "//" ) ) { RecordSingleLineCommentVariable( m_unknownParms, token, P ); continue; } if ( token.StartsWith( "/*" ) ) { RecordCommentVariable( m_unknownParms, token, P ); continue; } if ( token.EndsWith( "{" ) ) { // Handle problematic parms without space before their values token = token.Substring( 0, token.Length-1 ); P.m_Index--; } P.SkipSpaces(); switch ( token.ToLower() ) { case "stagesort": { string sortStageName = P.ReadString(); switch ( sortStageName.ToLower() ) { case "sortcoverage": m_sortStage = SORT_STAGE.sortCoverage; break; case "sortboatvolume": m_sortStage = SORT_STAGE.sortBoatVolume; break; case "sortemit": m_sortStage = SORT_STAGE.sortEmit; break; case "sortemitonly": m_sortStage = SORT_STAGE.sortEmitOnly; break; case "sortshadowwalk": m_sortStage = SORT_STAGE.sortShadowWalk; break; case "sortwater": m_sortStage = SORT_STAGE.sortWater; break; case "sortdecal": m_sortStage = SORT_STAGE.sortDecal; break; case "sorttranssort": m_sortStage = SORT_STAGE.sortTransSort; break; case "sorttrans": m_sortStage = SORT_STAGE.sortTrans; break; case "sortdarkvision": m_sortStage = SORT_STAGE.sortDarkVision; break; case "sorthud": m_sortStage = SORT_STAGE.sortHud; break; case "sortperturber": m_sortStage = SORT_STAGE.sortPerturber; break; case "sortautomap": m_sortStage = SORT_STAGE.sortAutomap; break; case "sortposttonemap": m_sortStage = SORT_STAGE.sortPostTonemap; break; default: throw new Exception( "Unhandled sort stage!" ); } break; } default: m_unknownParms.Add( token + " " + P.ReadToEOL() ); break; } } }
void RecordUnknownVariable( string _token, Parser P ) { string record = _token + "\t" + P.ReadToEOL(); m_unknownVariables.Add( record ); }
public void ParseScaleBias( Parser _P ) { float4 SB = _P.ReadFloat4(); m_UVScale.Set( SB.x, SB.y ); m_UVOffset.Set( SB.z, SB.w ); }
void RecordSingleLineCommentVariable( string _token, Parser P ) { RecordSingleLineCommentVariable( m_unknownVariables, _token, P ); }
void RecordUnknownOption( string _token, int value, Parser P ) { string record = _token + "\t" + value + P.ReadToEOL(); m_options.m_unknownOptions.Add( record ); }
void RecordSingleLineCommentOption( string _token, Parser P ) { string record = _token + P.ReadToEOL(); m_options.m_unknownOptions.Add( record ); }
void RecordForbiddenVariable( string _token, Parser P ) { string record = _token + "\t" + P.ReadToEOL(); m_forbiddenParms.Add( record ); }
void RecordCommentOption( string _token, Parser P ) { string comment = _token + P.SkipComment(); m_options.m_unknownOptions.Add( comment ); }
private void ParseOptions( string _options ) { try { Parser P = new Parser( _options ); while ( P.OK ) { string token = P.ReadString(); if ( token == null ) break; // Done! if ( token.StartsWith( "//" ) ) { RecordSingleLineCommentOption( token, P ); continue; } if ( token.StartsWith( "/*" ) ) { RecordCommentOption( token, P ); continue; } P.SkipSpaces(); if ( !P.IsNumeric() ) continue; // Ill-formed option? int value = P.ReadInteger(); switch ( token.ToLower() ) { case "glossindiffusealpha": m_options.m_glossInDiffuseAlpha = value != 0; break; case "alphatest": m_options.m_isAlphaTest = value != 0; break; case "ismasking": m_options.m_isMasking = value != 0; break; case "hasbumpmap": m_options.m_hasNormal = value != 0; break; case "hasspecularmap": m_options.m_hasSpecular = value != 0; break; case "hasocclusionmap": m_options.m_hasOcclusionMap = value != 0; break; case "hasglossmap": m_options.m_hasGloss = value != 0; break; case "hasmetallicmap": m_options.m_hasMetal = value != 0; break; case "hasemissivemap": m_options.m_hasEmissive = value != 0; break; case "translucency/enable": m_options.m_translucencyEnabled = value != 0; break; case "translucencyusevertexcolor": m_options.m_translucencyUseVertexColor = value != 0; break; case "extralayer": switch ( value ) { case 0: Layer0.m_mask = null; m_options.m_extraLayers = 0; break; case 1: Layer1.m_mask = null; m_options.m_extraLayers = 1; break; case 2: Layer2.m_mask = null; m_options.m_extraLayers = 2; break; default: throw new Exception( "Unsupported amount of extra layers!" ); } break; // LAYER 0 case "use_layer0_colorconstant": Layer0.m_useColorConstant = value != 0; break; case "layer0_uvset": switch ( value ) { case 0: Layer0.m_UVSet = Layer.UV_SET.UV0; break; case 1: Layer0.m_UVSet = Layer.UV_SET.UV1; break; default: throw new Exception( "Unsupported UV set!" ); } break; case "layer0_mask_uvset": switch ( value ) { case 0: Layer0.m_maskUVSet = Layer.UV_SET.UV0; break; case 1: Layer0.m_maskUVSet = Layer.UV_SET.UV1; break; default: throw new Exception( "Unsupported UV set!" ); } break; case "layer0_maskmode": switch ( value ) { case 0: Layer0.m_maskingMode = Layer.MASKING_MODE.VERTEX_COLOR; break; case 1: Layer0.m_maskingMode = Layer.MASKING_MODE.MASK_MAP; break; case 2: Layer0.m_maskingMode = Layer.MASKING_MODE.MASK_MAP_AND_VERTEX_COLOR; break; default: throw new Exception( "Unsupported UV set!" ); } break; // LAYER 1 case "use_layer1_colorconstant": Layer1.m_useColorConstant = value != 0; break; case "layer1_uvset": switch ( value ) { case 0: Layer1.m_UVSet = Layer.UV_SET.UV0; break; case 1: Layer1.m_UVSet = Layer.UV_SET.UV1; break; default: throw new Exception( "Unsupported UV set!" ); } break; case "layer1_mask_uvset": switch ( value ) { case 0: Layer1.m_maskUVSet = Layer.UV_SET.UV0; break; case 1: Layer1.m_maskUVSet = Layer.UV_SET.UV1; break; default: throw new Exception( "Unsupported UV set!" ); } break; case "layer1_maskmode": switch ( value ) { case 0: Layer1.m_maskingMode = Layer.MASKING_MODE.VERTEX_COLOR; break; case 1: Layer1.m_maskingMode = Layer.MASKING_MODE.MASK_MAP; break; case 2: Layer1.m_maskingMode = Layer.MASKING_MODE.MASK_MAP_AND_VERTEX_COLOR; break; default: throw new Exception( "Unsupported UV set!" ); } break; case "layer1_diffusereuselayer": switch ( value ) { case 0: Layer1.m_diffuseReUse = Layer.REUSE_MODE.DONT_REUSE; break; case 1: Layer1.m_diffuseReUse = Layer.REUSE_MODE.REUSE_LAYER0; break; default: throw new Exception( "Unsupported re-use mode!" ); } break; case "layer1_bumpreuselayer": switch ( value ) { case 0: Layer1.m_normalReUse = Layer.REUSE_MODE.DONT_REUSE; break; case 1: Layer1.m_normalReUse = Layer.REUSE_MODE.REUSE_LAYER0; break; default: throw new Exception( "Unsupported re-use mode!" ); } break; case "layer1_glossreuselayer": switch ( value ) { case 0: Layer1.m_glossReUse = Layer.REUSE_MODE.DONT_REUSE; break; case 1: Layer1.m_glossReUse = Layer.REUSE_MODE.REUSE_LAYER0; break; default: throw new Exception( "Unsupported re-use mode!" ); } break; case "layer1_specularreuselayer": switch ( value ) { case 0: Layer1.m_specularReUse = Layer.REUSE_MODE.DONT_REUSE; break; case 1: Layer1.m_specularReUse = Layer.REUSE_MODE.REUSE_LAYER0; break; default: throw new Exception( "Unsupported re-use mode!" ); } break; case "layer1_metallicreuselayer": switch ( value ) { case 0: Layer1.m_metalReUse = Layer.REUSE_MODE.DONT_REUSE; break; case 1: Layer1.m_metalReUse = Layer.REUSE_MODE.REUSE_LAYER0; break; default: throw new Exception( "Unsupported re-use mode!" ); } break; case "layer1_maskreuselayer": switch ( value ) { case 0: Layer1.m_maskReUse = Layer.REUSE_MODE.DONT_REUSE; break; case 1: Layer1.m_maskReUse = Layer.REUSE_MODE.REUSE_LAYER0; break; default: throw new Exception( "Unsupported re-use mode!" ); } break; // LAYER 2 case "use_layer2_colorconstant": Layer2.m_useColorConstant = value != 0; break; case "layer2_uvset": switch ( value ) { case 0: Layer2.m_UVSet = Layer.UV_SET.UV0; break; case 1: Layer2.m_UVSet = Layer.UV_SET.UV1; break; default: throw new Exception( "Unsupported UV set!" ); } break; case "layer2_mask_uvset": switch ( value ) { case 0: Layer2.m_maskUVSet = Layer.UV_SET.UV0; break; case 1: Layer2.m_maskUVSet = Layer.UV_SET.UV1; break; default: throw new Exception( "Unsupported UV set!" ); } break; case "layer2_maskmode": switch ( value ) { case 0: Layer2.m_maskingMode = Layer.MASKING_MODE.VERTEX_COLOR; break; case 1: Layer2.m_maskingMode = Layer.MASKING_MODE.MASK_MAP; break; case 2: Layer2.m_maskingMode = Layer.MASKING_MODE.MASK_MAP_AND_VERTEX_COLOR; break; default: throw new Exception( "Unsupported UV set!" ); } break; case "layer2_diffusereuselayer": switch ( value ) { case 0: Layer2.m_diffuseReUse = Layer.REUSE_MODE.DONT_REUSE; break; case 1: Layer2.m_diffuseReUse = Layer.REUSE_MODE.REUSE_LAYER0; break; case 2: Layer2.m_diffuseReUse = Layer.REUSE_MODE.REUSE_LAYER1; break; default: throw new Exception( "Unsupported re-use mode!" ); } break; case "layer2_bumpreuselayer": switch ( value ) { case 0: Layer2.m_normalReUse = Layer.REUSE_MODE.DONT_REUSE; break; case 1: Layer2.m_normalReUse = Layer.REUSE_MODE.REUSE_LAYER0; break; case 2: Layer2.m_normalReUse = Layer.REUSE_MODE.REUSE_LAYER1; break; default: throw new Exception( "Unsupported re-use mode!" ); } break; case "layer2_glossreuselayer": switch ( value ) { case 0: Layer2.m_glossReUse = Layer.REUSE_MODE.DONT_REUSE; break; case 1: Layer2.m_glossReUse = Layer.REUSE_MODE.REUSE_LAYER0; break; case 2: Layer2.m_glossReUse = Layer.REUSE_MODE.REUSE_LAYER1; break; default: throw new Exception( "Unsupported re-use mode!" ); } break; case "layer2_specularreuselayer": switch ( value ) { case 0: Layer2.m_specularReUse = Layer.REUSE_MODE.DONT_REUSE; break; case 1: Layer2.m_specularReUse = Layer.REUSE_MODE.REUSE_LAYER0; break; case 2: Layer2.m_specularReUse = Layer.REUSE_MODE.REUSE_LAYER1; break; default: throw new Exception( "Unsupported re-use mode!" ); } break; case "layer2_metallicreuselayer": switch ( value ) { case 0: Layer2.m_metalReUse = Layer.REUSE_MODE.DONT_REUSE; break; case 1: Layer2.m_metalReUse = Layer.REUSE_MODE.REUSE_LAYER0; break; case 2: Layer2.m_metalReUse = Layer.REUSE_MODE.REUSE_LAYER1; break; default: throw new Exception( "Unsupported re-use mode!" ); } break; case "layer2_maskreuselayer": switch ( value ) { case 0: Layer2.m_maskReUse = Layer.REUSE_MODE.DONT_REUSE; break; case 1: Layer2.m_maskReUse = Layer.REUSE_MODE.REUSE_LAYER0; break; case 2: Layer2.m_maskReUse = Layer.REUSE_MODE.REUSE_LAYER1; break; default: throw new Exception( "Unsupported re-use mode!" ); } break; default: CheckSafeOptionsTokens( token, value ); RecordUnknownOption( token, value, P ); break; } } } catch ( Exception _e ) { throw new Exception( "Failed parsing options block!", _e ); } }
public float4 ReadFloat4( string _block ) { Parser P = new Parser( _block ); float4 Result = new float4(); int coordinateIndex = 0; while ( P.OK ) { float value = P.ReadFloat(); P.ReadString(); // Skip separator switch ( coordinateIndex ) { case 0: Result.x = value; break; case 1: Result.y = value; break; case 2: Result.z = value; break; case 3: Result.w = value; break; default: Error( "Unexpected coordinate!" ); break; } coordinateIndex++; } return Result; }