Example #1
0
        public void BeginRenderPass(IGameContext gameContext, IRenderContext renderContext, IRenderPass previousPass,
                                    RenderTarget2D postProcessingSource)
        {
            _renderTarget = _renderTargetBackBufferUtilities.UpdateRenderTarget(_renderTarget, gameContext);

            // Blit to the capture target.
            _graphicsBlit.Blit(renderContext, postProcessingSource, _renderTarget);

            // Blit to the output.
            _graphicsBlit.Blit(renderContext, postProcessingSource);
        }
Example #2
0
        public void Render(IGameContext gameContext, IRenderContext renderContext)
        {
            try
            {
                renderContext.Render(gameContext);

                // NOTE: We MUST clear the depth buffer because OpenGL will not do it for us.
                renderContext.GraphicsDevice.Clear(
                    ClearOptions.DepthBuffer,
                    Microsoft.Xna.Framework.Color.Transparent,
                    renderContext.GraphicsDevice.Viewport.MaxDepth,
                    0);

                _primary   = _renderTargetBackBufferUtilities.UpdateRenderTarget(_primary, gameContext);
                _secondary = _renderTargetBackBufferUtilities.UpdateRenderTarget(_secondary, gameContext);

                if (_primary == null || _secondary == null)
                {
                    // These are null if the window is minimized or invalid, in which case we don't
                    // render anything anyway.
                    return;
                }

                var         standardRenderPasses       = _standardRenderPasses.ToArray();
                var         postProcessingRenderPasses = _postProcessingRenderPasses.ToArray();
                IRenderPass previousPass = null;
                IRenderPass nextPass     = null;

                var entities = gameContext.World.GetEntitiesForWorld(gameContext.Hierarchy).ToArray();

#if !DISABLE_PIPELINE_TARGETS
                renderContext.PushRenderTarget(_primary);
#endif

                for (var i = 0; i < standardRenderPasses.Length; i++)
                {
                    var pass = standardRenderPasses[i];
                    using (_profiler.Measure("r-" + pass.GetType().Name))
                    {
                        _isFirstRenderPass = previousPass == null;
                        _renderPass        = pass;
                        SetupRenderPassViewport(renderContext, pass);
                        pass.BeginRenderPass(gameContext, renderContext, previousPass, null);
                        previousPass = pass;
                        RenderPass(gameContext, renderContext, pass, entities);
                        if (i < standardRenderPasses.Length - 1)
                        {
                            nextPass = standardRenderPasses[i + 1];
                        }
                        else if (_transientStandardRenderPasses.Count > 0)
                        {
                            nextPass = _transientStandardRenderPasses[0];
                        }
                        else if (postProcessingRenderPasses.Length > 0)
                        {
                            nextPass = postProcessingRenderPasses[0];
                        }
                        else if (_transientPostProcessingRenderPasses.Count > 0)
                        {
                            nextPass = _transientPostProcessingRenderPasses[0];
                        }
                        else
                        {
                            nextPass = null;
                        }
                        pass.EndRenderPass(gameContext, renderContext, nextPass);
                    }
                }

                var loop = 100;
                while (_transientStandardRenderPasses.Count > 0 && loop-- >= 0)
                {
                    var transientStandardRenderPasses = _transientStandardRenderPasses.ToArray();
                    _transientStandardRenderPasses.Clear();

                    for (var i = 0; i < transientStandardRenderPasses.Length; i++)
                    {
                        var pass = transientStandardRenderPasses[i];
                        using (_profiler.Measure("r-" + pass.GetType().Name))
                        {
                            _isFirstRenderPass = previousPass == null;
                            _renderPass        = pass;
                            SetupRenderPassViewport(renderContext, pass);
                            pass.BeginRenderPass(gameContext, renderContext, previousPass, null);
                            previousPass = pass;
                            RenderPass(gameContext, renderContext, pass, entities);
                            if (i < transientStandardRenderPasses.Length - 1)
                            {
                                nextPass = transientStandardRenderPasses[i + 1];
                            }
                            else if (_transientStandardRenderPasses.Count > 0)
                            {
                                nextPass = _transientStandardRenderPasses[0];
                            }
                            else if (postProcessingRenderPasses.Length > 0)
                            {
                                nextPass = postProcessingRenderPasses[0];
                            }
                            else if (_transientPostProcessingRenderPasses.Count > 0)
                            {
                                nextPass = _transientPostProcessingRenderPasses[0];
                            }
                            else
                            {
                                nextPass = null;
                            }
                            pass.EndRenderPass(gameContext, renderContext, nextPass);
                        }
                    }
                }
                if (loop < 0)
                {
                    throw new InvalidOperationException(
                              "Exceeded the number of AppendTransientRenderPass iterations (100).  Ensure you " +
                              "are not unconditionally calling AppendTransientRenderPass within another render pass.");
                }

#if !DISABLE_PIPELINE_TARGETS
                renderContext.PopRenderTarget();
#endif

                if (postProcessingRenderPasses.Length == 0 && _transientPostProcessingRenderPasses.Count == 0)
                {
                    // Blit the primary render target to the backbuffer and return.
#if !DISABLE_PIPELINE_TARGETS
                    _graphicsBlit.Blit(renderContext, _primary);
#endif
                    return;
                }

                var currentSource = _primary;
                var currentDest   = _secondary;

#if !DISABLE_PIPELINE_TARGETS
                renderContext.PushRenderTarget(currentDest);
#endif

                for (var i = 0; i < postProcessingRenderPasses.Length; i++)
                {
                    var pass = postProcessingRenderPasses[i];
                    using (_profiler.Measure("r-" + pass.GetType().Name))
                    {
                        _isFirstRenderPass = previousPass == null;
                        _renderPass        = pass;
                        pass.BeginRenderPass(gameContext, renderContext, previousPass, currentSource);
                        previousPass = pass;
                        if (i < postProcessingRenderPasses.Length - 1)
                        {
                            nextPass = postProcessingRenderPasses[i + 1];
                        }
                        else if (_transientPostProcessingRenderPasses.Count > 0)
                        {
                            nextPass = _transientPostProcessingRenderPasses[0];
                        }
                        else
                        {
                            nextPass = null;
                        }
                        pass.EndRenderPass(gameContext, renderContext, nextPass);

                        var temp = currentSource;
                        currentSource = currentDest;
                        currentDest   = temp;

#if !DISABLE_PIPELINE_TARGETS
                        renderContext.PopRenderTarget();
                        renderContext.PushRenderTarget(currentDest);
#endif

                        // NOTE: This does not clear the new destination render target; it is expected that
                        // post-processing effects will fully overwrite the destination.
                    }
                }

                loop = 100;
                while (_transientPostProcessingRenderPasses.Count > 0 && loop-- >= 0)
                {
                    var transientPostProcessingRenderPasses = _transientPostProcessingRenderPasses.ToArray();
                    _transientPostProcessingRenderPasses.Clear();

                    for (var i = 0; i < transientPostProcessingRenderPasses.Length; i++)
                    {
                        var pass = transientPostProcessingRenderPasses[i];
                        using (_profiler.Measure("r-" + pass.GetType().Name))
                        {
                            _isFirstRenderPass = previousPass == null;
                            _renderPass        = pass;
                            pass.BeginRenderPass(gameContext, renderContext, previousPass, currentSource);
                            previousPass = pass;
                            if (i < transientPostProcessingRenderPasses.Length - 1)
                            {
                                nextPass = transientPostProcessingRenderPasses[i + 1];
                            }
                            else if (_transientPostProcessingRenderPasses.Count > 0)
                            {
                                nextPass = _transientPostProcessingRenderPasses[0];
                            }
                            else
                            {
                                nextPass = null;
                            }
                            pass.EndRenderPass(gameContext, renderContext, nextPass);

                            var temp = currentSource;
                            currentSource = currentDest;
                            currentDest   = temp;

#if !DISABLE_PIPELINE_TARGETS
                            renderContext.PopRenderTarget();
                            renderContext.PushRenderTarget(currentDest);
#endif

                            // NOTE: This does not clear the new destination render target; it is expected that
                            // post-processing effects will fully overwrite the destination.
                        }
                    }
                }
                if (loop < 0)
                {
                    throw new InvalidOperationException(
                              "Exceeded the number of AppendTransientRenderPass iterations (100).  Ensure you " +
                              "are not unconditionally calling AppendTransientRenderPass within another render pass.");
                }

#if !DISABLE_PIPELINE_TARGETS
                renderContext.PopRenderTarget();

                _graphicsBlit.Blit(renderContext, currentSource);
#endif
            }
            finally
            {
                _renderPass        = null;
                _isFirstRenderPass = false;
            }
        }
        public void Render(IGameContext gameContext, IRenderContext renderContext)
        {
            try
            {
                renderContext.Render(gameContext);

                _primary   = _renderTargetBackBufferUtilities.UpdateRenderTarget(_primary, gameContext);
                _secondary = _renderTargetBackBufferUtilities.UpdateRenderTarget(_secondary, gameContext);

                var standardRenderPasses       = _standardRenderPasses.ToArray();
                var postProcessingRenderPasses = _postProcessingRenderPasses.ToArray();
                //IRenderPass[] transientStandardRenderPasses;
                //IRenderPass[] transientPostProcessingRenderPasses;
                IRenderPass previousPass = null;
                IRenderPass nextPass     = null;

                var entities = gameContext.World.Entities.ToArray();

#if !DISABLE_PIPELINE_TARGETS
                renderContext.PushRenderTarget(_primary);
#endif

                for (var i = 0; i < standardRenderPasses.Length; i++)
                {
                    var pass = standardRenderPasses[i];
                    _isFirstRenderPass = previousPass == null;
                    _renderPass        = pass;
                    pass.BeginRenderPass(gameContext, renderContext, previousPass, null);
                    previousPass = pass;
                    RenderPass(gameContext, renderContext, entities);
                    if (i < standardRenderPasses.Length - 1)
                    {
                        nextPass = standardRenderPasses[i + 1];
                    }
                    else if (_transientStandardRenderPasses.Count > 0)
                    {
                        nextPass = _transientStandardRenderPasses[0];
                    }
                    else if (postProcessingRenderPasses.Length > 0)
                    {
                        nextPass = postProcessingRenderPasses[0];
                    }
                    else if (_transientPostProcessingRenderPasses.Count > 0)
                    {
                        nextPass = _transientPostProcessingRenderPasses[0];
                    }
                    else
                    {
                        nextPass = null;
                    }
                    pass.EndRenderPass(gameContext, renderContext, nextPass);
                }

                var loop = 100;
                while (_transientStandardRenderPasses.Count > 0 && loop-- >= 0)
                {
                    var transientStandardRenderPasses = _transientStandardRenderPasses.ToArray();
                    _transientStandardRenderPasses.Clear();

                    for (var i = 0; i < transientStandardRenderPasses.Length; i++)
                    {
                        var pass = transientStandardRenderPasses[i];
                        _isFirstRenderPass = previousPass == null;
                        _renderPass        = pass;
                        pass.BeginRenderPass(gameContext, renderContext, previousPass, null);
                        previousPass = pass;
                        RenderPass(gameContext, renderContext, entities);
                        if (i < transientStandardRenderPasses.Length - 1)
                        {
                            nextPass = transientStandardRenderPasses[i + 1];
                        }
                        else if (_transientStandardRenderPasses.Count > 0)
                        {
                            nextPass = _transientStandardRenderPasses[0];
                        }
                        else if (postProcessingRenderPasses.Length > 0)
                        {
                            nextPass = postProcessingRenderPasses[0];
                        }
                        else if (_transientPostProcessingRenderPasses.Count > 0)
                        {
                            nextPass = _transientPostProcessingRenderPasses[0];
                        }
                        else
                        {
                            nextPass = null;
                        }
                        pass.EndRenderPass(gameContext, renderContext, nextPass);
                    }
                }
                if (loop < 0)
                {
                    throw new InvalidOperationException(
                              "Exceeded the number of AppendTransientRenderPass iterations (100).  Ensure you " +
                              "are not unconditionally calling AppendTransientRenderPass within another render pass.");
                }

#if !DISABLE_PIPELINE_TARGETS
                renderContext.PopRenderTarget();
#endif

                if (postProcessingRenderPasses.Length == 0 && _transientPostProcessingRenderPasses.Count == 0)
                {
                    // Blit the primary render target to the backbuffer and return.
#if !DISABLE_PIPELINE_TARGETS
                    _graphicsBlit.Blit(renderContext, _primary);
#endif
                    return;
                }

                var currentSource = _primary;
                var currentDest   = _secondary;

#if !DISABLE_PIPELINE_TARGETS
                renderContext.PushRenderTarget(currentDest);
#endif

                for (var i = 0; i < postProcessingRenderPasses.Length; i++)
                {
                    var pass = postProcessingRenderPasses[i];
                    _isFirstRenderPass = previousPass == null;
                    _renderPass        = pass;
                    pass.BeginRenderPass(gameContext, renderContext, previousPass, currentSource);
                    previousPass = pass;
                    if (i < postProcessingRenderPasses.Length - 1)
                    {
                        nextPass = postProcessingRenderPasses[i + 1];
                    }
                    else if (_transientPostProcessingRenderPasses.Count > 0)
                    {
                        nextPass = _transientPostProcessingRenderPasses[0];
                    }
                    else
                    {
                        nextPass = null;
                    }
                    pass.EndRenderPass(gameContext, renderContext, nextPass);

                    var temp = currentSource;
                    currentSource = currentDest;
                    currentDest   = temp;

#if !DISABLE_PIPELINE_TARGETS
                    renderContext.PopRenderTarget();
                    renderContext.PushRenderTarget(currentDest);
#endif

                    // NOTE: This does not clear the new destination render target; it is expected that
                    // post-processing effects will fully overwrite the destination.
                }

                loop = 100;
                while (_transientPostProcessingRenderPasses.Count > 0 && loop-- >= 0)
                {
                    var transientPostProcessingRenderPasses = _transientPostProcessingRenderPasses.ToArray();
                    _transientPostProcessingRenderPasses.Clear();

                    for (var i = 0; i < transientPostProcessingRenderPasses.Length; i++)
                    {
                        var pass = transientPostProcessingRenderPasses[i];
                        _isFirstRenderPass = previousPass == null;
                        _renderPass        = pass;
                        pass.BeginRenderPass(gameContext, renderContext, previousPass, currentSource);
                        previousPass = pass;
                        if (i < transientPostProcessingRenderPasses.Length - 1)
                        {
                            nextPass = transientPostProcessingRenderPasses[i + 1];
                        }
                        else if (_transientPostProcessingRenderPasses.Count > 0)
                        {
                            nextPass = _transientPostProcessingRenderPasses[0];
                        }
                        else
                        {
                            nextPass = null;
                        }
                        pass.EndRenderPass(gameContext, renderContext, nextPass);

                        var temp = currentSource;
                        currentSource = currentDest;
                        currentDest   = temp;

#if !DISABLE_PIPELINE_TARGETS
                        renderContext.PopRenderTarget();
                        renderContext.PushRenderTarget(currentDest);
#endif

                        // NOTE: This does not clear the new destination render target; it is expected that
                        // post-processing effects will fully overwrite the destination.
                    }
                }
                if (loop < 0)
                {
                    throw new InvalidOperationException(
                              "Exceeded the number of AppendTransientRenderPass iterations (100).  Ensure you " +
                              "are not unconditionally calling AppendTransientRenderPass within another render pass.");
                }

#if !DISABLE_PIPELINE_TARGETS
                renderContext.PopRenderTarget();

                _graphicsBlit.Blit(renderContext, currentSource);
#endif
            }
            finally
            {
                _renderPass        = null;
                _isFirstRenderPass = false;
            }
        }