/// <summary> /// Creates a background layer that fills the entire screen with a specified color. /// </summary> /// <param name="spriteBatch">The default Game's SpriteBatch object.</param> /// <param name="color">The color used to fill the background layer.</param> public static void CreateBackgroundLayer(Color color) { PreventFumble(); if (!SketchManager.VerifyQueue()) { throw new RelatusException("CreateBackgroundLayer(spriteBatch, color) must be independent of any other Sketch calls.", new MethodOrderException()); } // Initialize a RenderTarget2D to accumulate all spriteBatch draw calls. accumulation = new RenderTarget2D(spriteBatch.GraphicsDevice, WindowManager.WindowWidth, WindowManager.WindowHeight); // Setup the GraphicsDevice with the new accumulation RenderTarget2D. spriteBatch.GraphicsDevice.SetRenderTarget(accumulation); spriteBatch.GraphicsDevice.Clear(color); // Reset the GraphicsDevice's RenderTarget. spriteBatch.GraphicsDevice.SetRenderTarget(null); spriteBatch.GraphicsDevice.Clear(Color.Transparent); // Relay the final RenderTarget2D to be drawn by the LayerManager. SketchManager.AddSketch(accumulation); }
/// <summary> /// Applies any attached effects to the current layer, and passes the layer to the SketchManager to be drawn. /// This method should be called after <see cref="Begin()"/>. /// </summary> public static void End() { SketchManager.RegisterStage(StageType.End); // Make sure that this method is always called after Begin(spriteBatch). if (!SketchManager.VerifyQueue(StageType.Setup, StageType.Begin, StageType.End)) { throw new RelatusException("End(spriteBatch) must be called after Begin(spriteBatch).", new MethodOrderException()); } // Reset the GraphicsDevice's RenderTarget. spriteBatch.GraphicsDevice.SetRenderTarget(null); if (shaders.Count > 0) { // Create an array of RenderTarget2Ds to store the accumulation of each shader. RenderTarget2D[] renderTargets = new RenderTarget2D[shaders.Count]; for (int i = 0; i < renderTargets.Length; i++) { renderTargets[i] = new RenderTarget2D(spriteBatch.GraphicsDevice, WindowManager.WindowWidth, WindowManager.WindowHeight); } int totalShaders = shaders.Count; Effect shader; // Iterate through all the shaders in the queue. for (int i = 0; i < totalShaders; i++) { shader = shaders.Dequeue(); // Setup the GraphicsDevice with the current RenderTarget2D. spriteBatch.GraphicsDevice.SetRenderTarget(renderTargets[i]); spriteBatch.GraphicsDevice.Clear(Color.Transparent); // Apply the shader. spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, shader, null); { spriteBatch.Draw(i == 0 ? accumulation : renderTargets[i - 1], Vector2.Zero, Color.White); } spriteBatch.End(); // Dispose of the current shader. shader.Dispose(); } // Initialize a RenderTarget2D to capture the result of all the shaders. result = new RenderTarget2D(spriteBatch.GraphicsDevice, WindowManager.WindowWidth, WindowManager.WindowHeight); // Setup the GraphicsDevice with the result RenderTarget2D. spriteBatch.GraphicsDevice.SetRenderTarget(result); spriteBatch.GraphicsDevice.Clear(Color.Transparent); spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, null); { spriteBatch.Draw(renderTargets[renderTargets.Length - 1], Vector2.Zero, Color.White); } spriteBatch.End(); // Dispose of all the unnecessary RenderTarget2Ds. for (int i = 0; i < renderTargets.Length; i++) { renderTargets[i].Dispose(); } accumulation.Dispose(); // Reset the GraphicsDevice's RenderTarget. spriteBatch.GraphicsDevice.SetRenderTarget(null); // Relay the final RenderTarget2D to be drawn by the LayerManager. if (!disableRelay) { SketchManager.AddSketch(result); } } else { // Relay the accumulation RenderTarget2D to be drawn by the LayerManager. if (!disableRelay) { SketchManager.AddSketch(accumulation); } // Otherwise set the result as the current accumulation to be intercepted by the user. else { result = accumulation; } } }