Ejemplo n.º 1
0
        /// <summary>
        /// Executes a SAS script block
        /// </summary>
        /// <param name="script">A list of script commands</param>
        /// <param name="render">The render delegate (is called once for every shader pass); <c>null</c> for global script</param>
        /// <param name="sceneSize">The size of the scene on the screen - leave empty for fullscreen</param>
        /// <param name="sceneMap">A texture containing the rendered scene for <see cref="PostShader"/>), <c>null</c> if the shader doesn't need it</param>
        /// <param name="passScipt">Is this a pass script?</param>
        protected void ExecuteScript(IEnumerable <SasScriptCommand> script, Action render, Size sceneSize, RenderTarget sceneMap, bool passScipt)
        {
            if (script == null)
            {
                throw new ArgumentNullException(nameof(script));
            }

            #region State variables
            //Color clearColor = Color.Black;
            //float clearDepth = 1.0f;
            //int clearStencil = 0;
            #endregion

            foreach (SasScriptCommand commandObject in script)
            {
                commandObject.Update();

                switch (commandObject.Command)
                {
                    #region Clear
                    //case SasScriptCommand.CommandType.Clear:
                    //    using (new ProfilerEvent("SAS script: clear"))
                    //    {
                    //        SasScriptClear clear = (SasScriptClear)commandObject;
                    //        switch (clear.ClearOption)
                    //        {
                    //            case SasScriptClear.ClearType.Color:
                    //                engine.Device.Clear(ClearFlags.Target, clearColor, clearDepth, clearStencil);
                    //                break;
                    //            case SasScriptClear.ClearType.Depth:
                    //                engine.Device.Clear(ClearFlags.ZBuffer, clearColor, clearDepth, clearStencil);
                    //                break;
                    //            case SasScriptClear.ClearType.Stencil:
                    //                engine.Device.Clear(ClearFlags.Stencil, clearColor, clearDepth, clearStencil);
                    //                break;
                    //            default:
                    //                break;
                    //        }
                    //    }
                    //    break;

                    //case SasScriptCommand.CommandType.ClearSetColor:
                    //    SasScriptClearSetColor clearSetColor = (SasScriptClearSetColor)commandObject;
                    //    clearColor = ColorHelper.Vector4ToColor(clearSetColor.Color);
                    //    break;

                    //case SasScriptCommand.CommandType.ClearSetDepth:
                    //    SasScriptClearSetDepth clearSetDepth = (SasScriptClearSetDepth)commandObject;
                    //    clearDepth = clearSetDepth.Depth;
                    //    break;

                    //case SasScriptCommand.CommandType.ClearSetStencil:
                    //    SasScriptClearSetStencil clearSetStencil = (SasScriptClearSetStencil)commandObject;
                    //    clearStencil = clearSetStencil.Stencil;
                    //    break;
                    #endregion

                    #region Render color target
                case SasScriptCommand.CommandType.RenderColorTarget:
                    var renderColorTarget = (SasScriptRenderColorTarget)commandObject;

                    if (renderColorTarget.TextureHandle == null)
                    {
                        Profiler.AddEvent("SAS script: restore original output target");
                        _activeRenderTarget = null;
                    }
                    else
                    {
                        if (passScipt)
                        {
                            using (new ProfilerEvent("SAS script: link new render target as output target"))
                            {
                                _activeRenderTarget = null;

                                // Try to reuse an existing RenderTarget
                                _availableRenderTargets.RemoveFirst(renderTarget =>
                                {
                                    if (renderTarget.Size == sceneSize)
                                    {
                                        // Found suitable RenderTarget
                                        _activeRenderTarget = renderTarget;
                                        _usedRenderTargets.Add(renderTarget);
                                        return(true);    // Stop looking, remove from the pool
                                    }

                                    return(false);    // Continue looking, keep in the pool
                                });

                                // Create new RenderTargets if necessary
                                if (_activeRenderTarget == null)
                                {
                                    _activeRenderTarget = new RenderTarget(Engine, sceneSize);
                                    _usedRenderTargets.Add(_activeRenderTarget);
                                }
                                Effect.SetTexture(renderColorTarget.TextureHandle, _activeRenderTarget);
                            }
                        }
                        else
                        {
                            using (new ProfilerEvent("SAS script: link existing render target to input variable"))
                                Effect.SetTexture(renderColorTarget.TextureHandle, sceneMap);
                        }
                    }
                    break;
                    #endregion

                    #region Render depth stencil target
                    //case SasScriptCommand.CommandType.RenderDepthStencilTarget:
                    //    SasScriptRenderDepthStencilTarget renderDepthTarget =
                    //        (SasScriptRenderDepthStencilTarget)commandObject;
                    //    SasTexture tex = mat.GetTexture(renderDepthTarget.TextureHandle);
                    //    if (tex != null)
                    //        renderer.SetDepthTarget(tex.DepthSurface);
                    //    else
                    //        renderer.SetDepthTarget(null);
                    //    break;
                    #endregion

                    #region Technique
                case SasScriptCommand.CommandType.Technique:
                    using (new ProfilerEvent("SAS script: set technique"))
                    {
                        var tech = (SasScriptTechnique)commandObject;
                        if (tech.Handle != null)
                        {
                            Effect.Technique = tech.Handle;
                        }
                    }
                    break;
                    #endregion

                    #region Pass
                case SasScriptCommand.CommandType.Pass:
                    if (render != null && !passScipt)
                    {
                        var pass = (SasScriptPass)commandObject;
                        using (new ProfilerEvent(() => "SAS script: pass " + pass.PassNum))
                        {
                            ExecuteScript(Passes[Effect.GetPass(Effect.Technique, pass.PassNum)], render, sceneSize, sceneMap, true);
                            Effect.BeginPass(pass.PassNum);
                            if (_activeRenderTarget == null)
                            {
                                render();
                            }
                            else
                            {
                                _activeRenderTarget.RenderTo(Engine.DrawQuadShader);
                            }
                            Effect.EndPass();
                        }
                    }
                    break;
                    #endregion
                }
            }
        }