Example #1
0
 /// <summary>
 ///     Internal constructor.  This class cannot be instantiated externally.
 /// </summary>
 /// <remarks>
 ///     Protected internal because this singleton will actually hold the instance of a subclass
 ///     created by a render system plugin.
 /// </remarks>
 protected internal CompositorManager()
 {
     if (instance == null)
     {
         instance = this;
     }
     rectangle = null;
 }
		public static void ParseScript( CompositorManager compositorManager, Stream data, string groupName, string fileName )
		{
			string file = ( (FileStream)data ).Name;
			string line = "";
			CompositorScriptContext context = new CompositorScriptContext();
			context.filename = file;
			context.lineNo = 0;

			StreamReader script = new StreamReader( data, System.Text.Encoding.UTF8 );

			// parse through the data to the end
			while ( ( line = ParseHelper.ReadLine( script ) ) != null )
			{
				context.lineNo++;
				string[] splitCmd;
				string[] args;
				string arg;
				// ignore blank lines and comments
				if ( !( line.Length == 0 || line.StartsWith( "//" ) ) )
				{
					context.line = line;
					splitCmd = SplitByWhitespace( line, 2 );
					string token = splitCmd[ 0 ];
					args = SplitArgs( splitCmd.Length == 2 ? splitCmd[ 1 ] : "" );
					arg = ( args.Length > 0 ? args[ 0 ] : "" );
					if ( context.section == CompositorScriptSection.None )
					{
						if ( token != "compositor" )
						{
							LogError( context, "First token is not 'compositor'!" );
							break; // Give up
						}
						string compositorName = RemoveQuotes( splitCmd[ 1 ].Trim() );
						context.compositor = (Compositor)compositorManager.Create( compositorName, groupName );
						context.section = CompositorScriptSection.Compositor;
						context.seenOpen = false;
						continue; // next line
					}
					else
					{
						if ( !context.seenOpen )
						{
							if ( token == "{" )
								context.seenOpen = true;
							else
								LogError( context, "Expected open brace; instead got {0}", token );
							continue; // next line
						}
						switch ( context.section )
						{
							case CompositorScriptSection.Compositor:
								switch ( token )
								{
									case "technique":
										context.section = CompositorScriptSection.Technique;
										context.technique = context.compositor.CreateTechnique();
										context.seenOpen = false;
										continue; // next line
									case "}":
										context.section = CompositorScriptSection.None;
										context.seenOpen = false;
										if ( context.technique == null )
										{
											LogError( context, "No 'technique' section in compositor" );
											continue;
										}
										break;
									default:
										LogError( context,
												 "After opening brace '{' of compositor definition, expected 'technique', but got '{0}'",
												 token );
										continue; // next line
								}
								break;
							case CompositorScriptSection.Technique:
								switch ( token )
								{
									case "texture":
										ParseTextureLine( context, args );
										break;
									case "target":
										context.section = CompositorScriptSection.Target;
										context.target = context.technique.CreateTargetPass();
										context.target.OutputName = arg.Trim();
										context.seenOpen = false;
										break;
									case "target_output":
										context.section = CompositorScriptSection.Target;
										context.target = context.technique.OutputTarget;
										context.seenOpen = false;
										break;
									case "compositor_logic":
										if ( !OptionCount( context, token, 1, args.Length ) )
											break;
										context.technique.CompositorLogicName = args[ 0 ].Trim();
										break;
									case "}":
										context.section = CompositorScriptSection.Compositor;
										context.seenOpen = true;
										break;
									default:
										LogIllegal( context, "technique", token );
										break;
								}
								break;
							case CompositorScriptSection.Target:
								switch ( token )
								{
									case "input":
										if ( OptionCount( context, token, 1, args.Length ) )
										{
											arg = args[ 0 ];
											if ( arg == "previous" )
												context.target.InputMode = CompositorInputMode.Previous;
											else if ( arg == "none" )
												context.target.InputMode = CompositorInputMode.None;
											else
												LogError( context, "Illegal 'input' arg '{0}'", arg );
										}
										break;
									case "only_initial":
										context.target.OnlyInitial = OnOffArg( context, token, args );
										break;
									case "visibility_mask":
										if ( !OptionCount( context, token, 1, args.Length ) )
											break;
										context.target.VisibilityMask = ParseUint( context, arg );
										break;
									case "lod_bias":
										if ( !OptionCount( context, token, 1, args.Length ) )
											break;
										context.target.LodBias = ParseInt( context, arg );
										break;
									case "material_scheme":
										if ( !OptionCount( context, token, 1, args.Length ) )
											break;
										context.target.MaterialScheme = arg.Trim();
										break;
									case "pass":
										context.section = CompositorScriptSection.Pass;
										context.pass = context.target.CreatePass();
										context.seenOpen = false;
										if ( !OptionCount( context, token, 1, args.Length ) && !OptionCount( context, token, 2, args.Length ) )
											break;
										arg = args[ 0 ].Trim();
										switch ( arg )
										{
											case "render_quad":
												context.pass.Type = CompositorPassType.RenderQuad;
												break;
											case "clear":
												context.pass.Type = CompositorPassType.Clear;
												break;
											case "stencil":
												context.pass.Type = CompositorPassType.Stencil;
												break;
											case "render_scene":
												context.pass.Type = CompositorPassType.RenderScene;
												break;
											case "render_custom":
												context.pass.Type = CompositorPassType.RenderCustom;
												context.pass.CustomType = args[ 1 ].Trim();
												break;
											default:
												LogError( context, "In line '{0}', unrecognized compositor pass type '{1}'", arg );
												break;
										}
										break;
									case "}":
										context.section = CompositorScriptSection.Technique;
										context.seenOpen = true;
										break;
									default:
										LogIllegal( context, "target", token );
										break;
								}
								break;
							case CompositorScriptSection.Pass:
								switch ( token )
								{
									case "first_render_queue":
										if ( !OptionCount( context, token, 1, args.Length ) )
											break;
										context.pass.FirstRenderQueue = (RenderQueueGroupID)ParseInt( context, args[ 0 ] );
										break;
									case "last_render_queue":
										if ( !OptionCount( context, token, 1, args.Length ) )
											break;
										context.pass.LastRenderQueue = (RenderQueueGroupID)ParseInt( context, args[ 0 ] );
										break;
									case "identifier":
										if ( !OptionCount( context, token, 1, args.Length ) )
											break;
										context.pass.Identifier = ParseUint( context, args[ 0 ] );
										break;
									case "material":
										if ( !OptionCount( context, token, 1, args.Length ) )
											break;
										context.pass.MaterialName = args[ 0 ].Trim();
										break;
									case "input":
										if ( !OptionCount( context, token, 3, args.Length ) )
											break;
										int index = 0;
										if ( args.Length == 3 )
											index = ParseInt( context, args[ 2 ] );
										context.pass.SetInput( ParseInt( context, args[ 0 ] ), args[ 1 ].Trim(), index );
										break;
									case "clear":
										context.section = CompositorScriptSection.Clear;
										context.seenOpen = false;
										break;
									case "stencil":
										context.section = CompositorScriptSection.Clear;
										context.seenOpen = false;
										break;
									case "}":
										context.section = CompositorScriptSection.Target;
										context.seenOpen = true;
										break;
									default:
										LogIllegal( context, "pass", token );
										break;
								}
								break;
							case CompositorScriptSection.Clear:
								switch ( token )
								{
									case "buffers":
										FrameBufferType fb = (FrameBufferType)0;
										foreach ( string cb in args )
										{
											switch ( cb )
											{
												case "colour":
													fb |= FrameBufferType.Color;
													break;
												case "color":
													fb |= FrameBufferType.Color;
													break;
												case "depth":
													fb |= FrameBufferType.Depth;
													break;
												case "stencil":
													fb |= FrameBufferType.Stencil;
													break;
												default:
													LogError( context, "When parsing pass clear buffers options, illegal option '{0}'", cb );
													break;
											}
										}
										break;
									case "colour":
										context.pass.ClearColor = ParseClearColor( context, args );
										break;
									case "color":
										context.pass.ClearColor = ParseClearColor( context, args );
										break;
									case "depth_value":
										if ( !OptionCount( context, token, 1, args.Length ) )
											break;
										context.pass.ClearDepth = ParseFloat( context, args[ 0 ] );
										break;
									case "stencil_value":
										if ( !OptionCount( context, token, 1, args.Length ) )
											break;
										context.pass.ClearDepth = ParseInt( context, args[ 0 ] );
										break;
									case "}":
										context.section = CompositorScriptSection.Pass;
										context.seenOpen = true;
										break;
									default:
										LogIllegal( context, "clear", token );
										break;
								}
								break;
							case CompositorScriptSection.Stencil:
								switch ( token )
								{
									case "check":
										context.pass.StencilCheck = OnOffArg( context, token, args );
										break;
									case "compare_func":
										if ( !OptionCount( context, token, 1, args.Length ) )
											break;
										context.pass.StencilFunc = ParseCompareFunc( context, arg );
										break;
									case "ref_value":
										if ( !OptionCount( context, token, 1, args.Length ) )
											break;
										context.pass.StencilRefValue = ParseInt( context, arg );
										break;
									case "mask":
										if ( !OptionCount( context, token, 1, args.Length ) )
											break;
										context.pass.StencilMask = ParseInt( context, arg );
										break;
									case "fail_op":
										if ( !OptionCount( context, token, 1, args.Length ) )
											break;
										context.pass.StencilFailOp = ParseStencilOperation( context, arg );
										break;
									case "depth_fail_op":
										if ( !OptionCount( context, token, 1, args.Length ) )
											break;
										context.pass.StencilDepthFailOp = ParseStencilOperation( context, arg );
										break;
									case "pass_op":
										if ( !OptionCount( context, token, 1, args.Length ) )
											break;
										context.pass.StencilPassOp = ParseStencilOperation( context, arg );
										break;
									case "two_sided":
										if ( !OptionCount( context, token, 1, args.Length ) )
											break;
										context.pass.StencilTwoSidedOperation = OnOffArg( context, token, args );
										break;
									case "}":
										context.section = CompositorScriptSection.Pass;
										context.seenOpen = true;
										break;
									default:
										LogIllegal( context, "stencil", token );
										break;
								}
								break;
							default:
								LogError( context, "Internal compositor parser error: illegal context" );
								break;
						}
					} // if
				} // if
			} // while
			if ( context.section != CompositorScriptSection.None )
				LogError( context, "At end of file, unterminated compositor script!" );
		}
Example #3
0
        public static void ParseScript(CompositorManager compositorManager, Stream data, string groupName, string fileName)
        {
            var line    = "";
            var context = new CompositorScriptContext();

            context.filename = fileName + (data is FileStream ? " (" + (data as FileStream).Name + ")" : "");
            context.lineNo   = 0;

            var script = new StreamReader(data, System.Text.Encoding.UTF8);

            // parse through the data to the end
            while ((line = ParseHelper.ReadLine(script)) != null)
            {
                context.lineNo++;
                string[] splitCmd;
                string[] args;
                string   arg;
                // ignore blank lines and comments
                if (!(line.Length == 0 || line.StartsWith("//")))
                {
                    context.line = line;
                    splitCmd     = SplitByWhitespace(line, 2);
                    var token = splitCmd[0];
                    args = SplitArgs(splitCmd.Length == 2 ? splitCmd[1] : "");
                    arg  = (args.Length > 0 ? args[0] : "");
                    if (context.section == CompositorScriptSection.None)
                    {
                        if (token != "compositor")
                        {
                            LogError(context, "First token is not 'compositor'!");
                            break; // Give up
                        }
                        var compositorName = RemoveQuotes(splitCmd[1].Trim());
                        context.compositor = (Compositor)compositorManager.Create(compositorName, groupName);
                        context.section    = CompositorScriptSection.Compositor;
                        context.seenOpen   = false;
                        continue; // next line
                    }
                    else
                    {
                        if (!context.seenOpen)
                        {
                            if (token == "{")
                            {
                                context.seenOpen = true;
                            }
                            else
                            {
                                LogError(context, "Expected open brace; instead got {0}", token);
                            }
                            continue; // next line
                        }
                        switch (context.section)
                        {
                        case CompositorScriptSection.Compositor:
                            switch (token)
                            {
                            case "technique":
                                context.section   = CompositorScriptSection.Technique;
                                context.technique = context.compositor.CreateTechnique();
                                context.seenOpen  = false;
                                continue;         // next line

                            case "}":
                                context.section  = CompositorScriptSection.None;
                                context.seenOpen = false;
                                if (context.technique == null)
                                {
                                    LogError(context, "No 'technique' section in compositor");
                                    continue;
                                }
                                break;

                            default:
                                LogError(context, "After opening brace '{' of compositor definition, expected 'technique', but got '{0}'",
                                         token);
                                continue;         // next line
                            }
                            break;

                        case CompositorScriptSection.Technique:
                            switch (token)
                            {
                            case "texture":
                                ParseTextureLine(context, args);
                                break;

                            case "target":
                                context.section           = CompositorScriptSection.Target;
                                context.target            = context.technique.CreateTargetPass();
                                context.target.OutputName = arg.Trim();
                                context.seenOpen          = false;
                                break;

                            case "target_output":
                                context.section  = CompositorScriptSection.Target;
                                context.target   = context.technique.OutputTarget;
                                context.seenOpen = false;
                                break;

                            case "compositor_logic":
                                if (!OptionCount(context, token, 1, args.Length))
                                {
                                    break;
                                }
                                context.technique.CompositorLogicName = args[0].Trim();
                                break;

                            case "}":
                                context.section  = CompositorScriptSection.Compositor;
                                context.seenOpen = true;
                                break;

                            default:
                                LogIllegal(context, "technique", token);
                                break;
                            }
                            break;

                        case CompositorScriptSection.Target:
                            switch (token)
                            {
                            case "input":
                                if (OptionCount(context, token, 1, args.Length))
                                {
                                    arg = args[0];
                                    if (arg == "previous")
                                    {
                                        context.target.InputMode = CompositorInputMode.Previous;
                                    }
                                    else if (arg == "none")
                                    {
                                        context.target.InputMode = CompositorInputMode.None;
                                    }
                                    else
                                    {
                                        LogError(context, "Illegal 'input' arg '{0}'", arg);
                                    }
                                }
                                break;

                            case "only_initial":
                                context.target.OnlyInitial = OnOffArg(context, token, args);
                                break;

                            case "visibility_mask":
                                if (!OptionCount(context, token, 1, args.Length))
                                {
                                    break;
                                }
                                context.target.VisibilityMask = ParseUint(context, arg);
                                break;

                            case "lod_bias":
                                if (!OptionCount(context, token, 1, args.Length))
                                {
                                    break;
                                }
                                context.target.LodBias = ParseInt(context, arg);
                                break;

                            case "material_scheme":
                                if (!OptionCount(context, token, 1, args.Length))
                                {
                                    break;
                                }
                                context.target.MaterialScheme = arg.Trim();
                                break;

                            case "pass":
                                context.section  = CompositorScriptSection.Pass;
                                context.pass     = context.target.CreatePass();
                                context.seenOpen = false;
                                if (!OptionCount(context, token, 1, args.Length) && !OptionCount(context, token, 2, args.Length))
                                {
                                    break;
                                }
                                arg = args[0].Trim();
                                switch (arg)
                                {
                                case "render_quad":
                                    context.pass.Type = CompositorPassType.RenderQuad;
                                    break;

                                case "clear":
                                    context.pass.Type = CompositorPassType.Clear;
                                    break;

                                case "stencil":
                                    context.pass.Type = CompositorPassType.Stencil;
                                    break;

                                case "render_scene":
                                    context.pass.Type = CompositorPassType.RenderScene;
                                    break;

                                case "render_custom":
                                    context.pass.Type       = CompositorPassType.RenderCustom;
                                    context.pass.CustomType = args[1].Trim();
                                    break;

                                default:
                                    LogError(context, "In line '{0}', unrecognized compositor pass type '{1}'", arg);
                                    break;
                                }
                                break;

                            case "}":
                                context.section  = CompositorScriptSection.Technique;
                                context.seenOpen = true;
                                break;

                            default:
                                LogIllegal(context, "target", token);
                                break;
                            }
                            break;

                        case CompositorScriptSection.Pass:
                            switch (token)
                            {
                            case "first_render_queue":
                                if (!OptionCount(context, token, 1, args.Length))
                                {
                                    break;
                                }
                                context.pass.FirstRenderQueue = (RenderQueueGroupID)ParseInt(context, args[0]);
                                break;

                            case "last_render_queue":
                                if (!OptionCount(context, token, 1, args.Length))
                                {
                                    break;
                                }
                                context.pass.LastRenderQueue = (RenderQueueGroupID)ParseInt(context, args[0]);
                                break;

                            case "identifier":
                                if (!OptionCount(context, token, 1, args.Length))
                                {
                                    break;
                                }
                                context.pass.Identifier = ParseUint(context, args[0]);
                                break;

                            case "material":
                                if (!OptionCount(context, token, 1, args.Length))
                                {
                                    break;
                                }
                                context.pass.MaterialName = args[0].Trim();
                                break;

                            case "input":
                                if (!OptionCount(context, token, 3, args.Length))
                                {
                                    break;
                                }
                                var index = 0;
                                if (args.Length == 3)
                                {
                                    index = ParseInt(context, args[2]);
                                }
                                context.pass.SetInput(ParseInt(context, args[0]), args[1].Trim(), index);
                                break;

                            case "clear":
                                context.section  = CompositorScriptSection.Clear;
                                context.seenOpen = false;
                                break;

                            case "stencil":
                                context.section  = CompositorScriptSection.Clear;
                                context.seenOpen = false;
                                break;

                            case "}":
                                context.section  = CompositorScriptSection.Target;
                                context.seenOpen = true;
                                break;

                            default:
                                LogIllegal(context, "pass", token);
                                break;
                            }
                            break;

                        case CompositorScriptSection.Clear:
                            switch (token)
                            {
                            case "buffers":
                                var fb = (FrameBufferType)0;
                                foreach (var cb in args)
                                {
                                    switch (cb)
                                    {
                                    case "colour":
                                        fb |= FrameBufferType.Color;
                                        break;

                                    case "color":
                                        fb |= FrameBufferType.Color;
                                        break;

                                    case "depth":
                                        fb |= FrameBufferType.Depth;
                                        break;

                                    case "stencil":
                                        fb |= FrameBufferType.Stencil;
                                        break;

                                    default:
                                        LogError(context, "When parsing pass clear buffers options, illegal option '{0}'", cb);
                                        break;
                                    }
                                }
                                break;

                            case "colour":
                                context.pass.ClearColor = ParseClearColor(context, args);
                                break;

                            case "color":
                                context.pass.ClearColor = ParseClearColor(context, args);
                                break;

                            case "depth_value":
                                if (!OptionCount(context, token, 1, args.Length))
                                {
                                    break;
                                }
                                context.pass.ClearDepth = ParseFloat(context, args[0]);
                                break;

                            case "stencil_value":
                                if (!OptionCount(context, token, 1, args.Length))
                                {
                                    break;
                                }
                                context.pass.ClearDepth = ParseInt(context, args[0]);
                                break;

                            case "}":
                                context.section  = CompositorScriptSection.Pass;
                                context.seenOpen = true;
                                break;

                            default:
                                LogIllegal(context, "clear", token);
                                break;
                            }
                            break;

                        case CompositorScriptSection.Stencil:
                            switch (token)
                            {
                            case "check":
                                context.pass.StencilCheck = OnOffArg(context, token, args);
                                break;

                            case "compare_func":
                                if (!OptionCount(context, token, 1, args.Length))
                                {
                                    break;
                                }
                                context.pass.StencilFunc = ParseCompareFunc(context, arg);
                                break;

                            case "ref_value":
                                if (!OptionCount(context, token, 1, args.Length))
                                {
                                    break;
                                }
                                context.pass.StencilRefValue = ParseInt(context, arg);
                                break;

                            case "mask":
                                if (!OptionCount(context, token, 1, args.Length))
                                {
                                    break;
                                }
                                context.pass.StencilMask = ParseInt(context, arg);
                                break;

                            case "fail_op":
                                if (!OptionCount(context, token, 1, args.Length))
                                {
                                    break;
                                }
                                context.pass.StencilFailOp = ParseStencilOperation(context, arg);
                                break;

                            case "depth_fail_op":
                                if (!OptionCount(context, token, 1, args.Length))
                                {
                                    break;
                                }
                                context.pass.StencilDepthFailOp = ParseStencilOperation(context, arg);
                                break;

                            case "pass_op":
                                if (!OptionCount(context, token, 1, args.Length))
                                {
                                    break;
                                }
                                context.pass.StencilPassOp = ParseStencilOperation(context, arg);
                                break;

                            case "two_sided":
                                if (!OptionCount(context, token, 1, args.Length))
                                {
                                    break;
                                }
                                context.pass.StencilTwoSidedOperation = OnOffArg(context, token, args);
                                break;

                            case "}":
                                context.section  = CompositorScriptSection.Pass;
                                context.seenOpen = true;
                                break;

                            default:
                                LogIllegal(context, "stencil", token);
                                break;
                            }
                            break;

                        default:
                            LogError(context, "Internal compositor parser error: illegal context");
                            break;
                        }
                    } // if
                }     // if
            }         // while
            if (context.section != CompositorScriptSection.None)
            {
                LogError(context, "At end of file, unterminated compositor script!");
            }
        }
 /// <summary>
 ///     Internal constructor.  This class cannot be instantiated externally.
 /// </summary>
 /// <remarks>
 ///     Protected internal because this singleton will actually hold the instance of a subclass
 ///     created by a render system plugin.
 /// </remarks>
 protected internal CompositorManager()
 {
     if (instance == null) {
         instance = this;
     }
     rectangle = null;
 }