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); }
public override void Render(IGameContext gameContext, IRenderContext renderContext) { base.Render(gameContext, renderContext); if (renderContext.IsCurrentRenderPass<I2DDirectRenderPass>()) { if (_analyzerEntity.TopLeftNormalized != null && _analyzerEntity.TopRightNormalized != null && _analyzerEntity.BottomLeftNormalized != null && _analyzerEntity.BottomRightNormalized != null) { _cachedTopLeft = _analyzerEntity.TopLeftNormalized; _cachedTopRight = _analyzerEntity.TopRightNormalized; _cachedBottomLeft = _analyzerEntity.BottomLeftNormalized; _cachedBottomRight = _analyzerEntity.BottomRightNormalized; } if (_cachedTopLeft != null && _cachedTopRight != null && _cachedBottomLeft != null && _cachedBottomRight != null) { _warpFromPolygonEffect.Effect.Parameters["TopLeft"].SetValue(_cachedTopLeft.Value); _warpFromPolygonEffect.Effect.Parameters["TopRight"].SetValue(_cachedTopRight.Value); _warpFromPolygonEffect.Effect.Parameters["BottomLeft"].SetValue(_cachedBottomLeft.Value); _warpFromPolygonEffect.Effect.Parameters["BottomRight"].SetValue(_cachedBottomRight.Value); _warpFromPolygonEffect.Effect.Parameters["Alpha"].SetValue(_alpha); _graphicsBlit.Blit( renderContext, _webcamEntity.VideoCaptureFrame, null, _warpFromPolygonEffect.Effect, BlendState.AlphaBlend); } } }
public void BeginRenderPass(IGameContext gameContext, IRenderContext renderContext, IRenderPass previousPass, RenderTarget2D postProcessingSource) { var effect = GetEffect(); if (effect != null) { _graphicsBlit.Blit(renderContext, postProcessingSource, null, effect); } }
public void BeginRenderPass(IGameContext gameContext, IRenderContext renderContext, IRenderPass previousPass, RenderTarget2D postProcessingSource) { if (!_invertEffect.IsReady) { return; } _graphicsBlit.Blit(renderContext, postProcessingSource, null, _invertEffect.Asset.Effect); }
public void BeginRenderPass(IGameContext gameContext, IRenderContext renderContext, IRenderPass previousPass, RenderTarget2D postProcessingSource) { if (RenderPipelineStateAvailable != null) { RenderPipelineStateAvailable(postProcessingSource); } // Blit to the output. _graphicsBlit.Blit(renderContext, postProcessingSource); }
public void BeginRenderPass(IGameContext gameContext, IRenderContext renderContext, IRenderPass previousPass, RenderTarget2D postProcessingSource) { // TODO Make iterations work. _blurEffect.NativeEffect.Parameters["PixelWidth"].SetValue(1f / postProcessingSource.Width); _blurEffect.NativeEffect.Parameters["PixelHeight"].SetValue(1f / postProcessingSource.Height); //_blurEffect.CurrentTechnique.Passes[0].Apply(); // Parameters will get applied when blitting occurs. _graphicsBlit.Blit(renderContext, postProcessingSource, null, _blurEffect); }
public void WriteThumbnailIfNecessary(IGameContext gameContext, IRenderContext renderContext) { var path = _projectManager?.Project?.ProjectPath; if (path == null || !path.Exists) { return; } var editorPath = Path.Combine(Path.Combine(path.FullName, "Build", "Editor")); Directory.CreateDirectory(editorPath); var thumbnailFile = new FileInfo(Path.Combine(editorPath, "Thumbnail.png")); var startTime = _loadedGame.GetPlayingStartTime(); if (startTime != null && (DateTime.UtcNow - startTime.Value).TotalMinutes >= 1) { if (!thumbnailFile.Exists || thumbnailFile.LastWriteTimeUtc < DateTime.UtcNow.AddHours(-4)) { _consoleHandle.LogInfo("Sampling current game screen as thumbnail for project..."); var srt = _loadedGame.GetCurrentGameRenderTarget(); var rt = new RenderTarget2D(renderContext.GraphicsDevice, 128, 128, false, SurfaceFormat.Color, DepthFormat.None); _graphicsBlit.Blit(renderContext, srt, rt); try { using (var writer = new FileStream(thumbnailFile.FullName, FileMode.Create, FileAccess.Write)) { rt.SaveAsPng(writer, 128, 128); } } catch { thumbnailFile.Delete(); throw; } rt.Dispose(); } } }
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 BeginRenderPass(IGameContext gameContext, IRenderContext renderContext, IRenderPass previousPass, RenderTarget2D postProcessingSource) { _graphicsBlit.Blit(renderContext, postProcessingSource, null, _effect); }
public void BeginRenderPass( IGameContext gameContext, IRenderContext renderContext, IRenderPass previousPass, RenderTarget2D postProcessingSource) { _colorRenderTarget = _renderTargetBackBufferUtilities.UpdateCustomRenderTarget(_colorRenderTarget, gameContext, SurfaceFormat.Color, DepthFormat.Depth24, null); _normalRenderTarget = _renderTargetBackBufferUtilities.UpdateCustomRenderTarget(_normalRenderTarget, gameContext, SurfaceFormat.Color, DepthFormat.None, null); _depthRenderTarget = _renderTargetBackBufferUtilities.UpdateCustomRenderTarget(_depthRenderTarget, gameContext, SurfaceFormat.Single, DepthFormat.None, null); _specularRenderTarget = _renderTargetBackBufferUtilities.UpdateCustomRenderTarget(_specularRenderTarget, gameContext, SurfaceFormat.Color, DepthFormat.None, null); _diffuseLightRenderTarget = _renderTargetBackBufferUtilities.UpdateCustomRenderTarget(_diffuseLightRenderTarget, gameContext, null, DepthFormat.None, null); _specularLightRenderTarget = _renderTargetBackBufferUtilities.UpdateCustomRenderTarget(_specularLightRenderTarget, gameContext, null, DepthFormat.None, null); if (_rasterizerStateCullNone == null) { _rasterizerStateCullNone = new RasterizerState(); _rasterizerStateCullNone.CullMode = CullMode.None; _rasterizerStateCullNone.FillMode = FillMode.Solid; _rasterizerStateCullNone.DepthBias = 0; _rasterizerStateCullNone.MultiSampleAntiAlias = true; _rasterizerStateCullNone.ScissorTestEnable = false; _rasterizerStateCullNone.SlopeScaleDepthBias = 0; _rasterizerStateCullNone.DepthClipEnable = true; } if (_rasterizerStateCullClockwiseFace == null) { _rasterizerStateCullClockwiseFace = new RasterizerState(); _rasterizerStateCullClockwiseFace.CullMode = CullMode.CullClockwiseFace; _rasterizerStateCullClockwiseFace.FillMode = FillMode.Solid; _rasterizerStateCullClockwiseFace.DepthBias = 0; _rasterizerStateCullClockwiseFace.MultiSampleAntiAlias = true; _rasterizerStateCullClockwiseFace.ScissorTestEnable = false; _rasterizerStateCullClockwiseFace.SlopeScaleDepthBias = 0; _rasterizerStateCullClockwiseFace.DepthClipEnable = true; } if (_rasterizerStateCullCounterClockwiseFace == null) { _rasterizerStateCullCounterClockwiseFace = new RasterizerState(); _rasterizerStateCullCounterClockwiseFace.CullMode = CullMode.CullCounterClockwiseFace; _rasterizerStateCullCounterClockwiseFace.FillMode = FillMode.Solid; _rasterizerStateCullCounterClockwiseFace.DepthBias = 0; _rasterizerStateCullCounterClockwiseFace.MultiSampleAntiAlias = true; _rasterizerStateCullCounterClockwiseFace.ScissorTestEnable = false; _rasterizerStateCullCounterClockwiseFace.SlopeScaleDepthBias = 0; _rasterizerStateCullCounterClockwiseFace.DepthClipEnable = true; } if (_depthStencilState == null) { _depthStencilState = DepthStencilState.Default; } if (_lightDepthStencilState == null) { _lightDepthStencilState = DepthStencilState.None; } if (_blendState == null) { _blendState = BlendState.Opaque; } if (_lightBlendState == null) { _lightBlendState = BlendState.AlphaBlend; } renderContext.PushRenderTarget( _colorRenderTarget, _normalRenderTarget, _depthRenderTarget, _specularRenderTarget); if (ClearDepthBuffer || ClearTarget) { var target = ClearDepthBuffer ? ClearOptions.DepthBuffer : ClearOptions.Target; if (ClearDepthBuffer && ClearTarget) { target = ClearOptions.DepthBuffer | ClearOptions.Target; } renderContext.GraphicsDevice.Clear( target, Microsoft.Xna.Framework.Color.Transparent, renderContext.GraphicsDevice.Viewport.MaxDepth, 0); } // Clear the geometry buffer before moving into main rendering. _graphicsBlit.Blit( renderContext, null, null, _gbufferClearEffect.Effect); _previousDepthStencilState = renderContext.GraphicsDevice.DepthStencilState; _previousRasterizerState = renderContext.GraphicsDevice.RasterizerState; _previousBlendState = renderContext.GraphicsDevice.BlendState; renderContext.GraphicsDevice.DepthStencilState = _depthStencilState; renderContext.GraphicsDevice.RasterizerState = _rasterizerStateCullCounterClockwiseFace; renderContext.GraphicsDevice.BlendState = _blendState; }
public RenderPipelineWorld( IAssetManager assetManager, I2DRenderUtilities renderUtilities, IGraphicsFactory graphicsFactory, IAssert assert, ITestAttachment testAttachment, IRenderTargetBackBufferUtilities renderTargetBackBufferUtilities, IGraphicsBlit graphicsBlit) { _renderUtilities = renderUtilities; _assert = assert; _testAttachment = testAttachment; _texture = assetManager.Get <TextureAsset>("texture.Player"); _invertPostProcess = graphicsFactory.CreateInvertPostProcessingRenderPass(); _blurPostProcess = graphicsFactory.CreateBlurPostProcessingRenderPass(); _customPostProcess = graphicsFactory.CreateCustomPostProcessingRenderPass("effect.MakeRed"); _captureInlinePostProcess = graphicsFactory.CreateCaptureInlinePostProcessingRenderPass(); _renderTargetBackBufferUtilities = renderTargetBackBufferUtilities; _graphicsBlit = graphicsBlit; _captureInlinePostProcess.RenderPipelineStateAvailable = (gameContext, renderContext, previousPass, d) => { if (!_isValidRun) { return; } _renderTarget = _renderTargetBackBufferUtilities.UpdateCustomRenderTarget(_renderTarget, renderContext, SurfaceFormat.Color, DepthFormat.None, 1); // Blit to the capture target. _graphicsBlit.Blit(renderContext, d, _renderTarget); #if MANUAL_TEST #elif RECORDING using (var writer = new StreamWriter("output" + _frame + ".png")) { _renderTarget.SaveAsPng(writer.BaseStream, Width, Height); } #else var baseStream = typeof(RenderPipelineWorld).Assembly.GetManifestResourceStream( "Protogame.Tests.Expected.RenderPipeline.output" + _frame + ".png"); _assert.NotNull(baseStream); var memoryStream = new MemoryStream(); _renderTarget.SaveAsPng(memoryStream, Width, Height); // ReSharper disable once AssignNullToNotNullAttribute var expected = new Bitmap(baseStream); var actual = new Bitmap(memoryStream); _assert.Equal(expected.Height, actual.Height); _assert.Equal(expected.Width, actual.Width); var totalPixelValues = 0L; var incorrectPixelValues = 0L; for (var x = 0; x < expected.Width; x++) { for (var y = 0; y < expected.Height; y++) { var expectedPixel = expected.GetPixel(x, y); var actualPixel = actual.GetPixel(x, y); totalPixelValues += 255 * 4; if (expectedPixel != actualPixel) { var diffA = System.Math.Abs((int)actualPixel.A - (int)expectedPixel.A); var diffR = System.Math.Abs((int)actualPixel.R - (int)expectedPixel.R); var diffG = System.Math.Abs((int)actualPixel.G - (int)expectedPixel.G); var diffB = System.Math.Abs((int)actualPixel.B - (int)expectedPixel.B); incorrectPixelValues += (diffA + diffR + diffG + diffB); } } } var percentage = (100 - ((incorrectPixelValues / (double)totalPixelValues) * 100f)); var combination = _combinations[_frame % _combinations.Count]; _testAttachment.Attach("name-" + combination.Id, combination.Name); _testAttachment.Attach("expected-" + combination.Id, baseStream); _testAttachment.Attach("actual-" + combination.Id, memoryStream); _testAttachment.Attach("threshold-" + combination.Id, 99.9); _testAttachment.Attach("measured-" + combination.Id, percentage); if (percentage <= 99.9f) { combination.FailureMessage = "The actual rendered image did not match the expected image close enough (99.9%)."; } //memoryStream.Dispose(); //baseStream.Dispose(); #endif #if MANUAL_TEST _manualTest++; if (_manualTest % 60 == 0) { _frame++; } #else _frame++; #endif }; this.Entities = new List <IEntity>(); }
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; } }