internal static Texture2D ApplyEffects(Texture2D texture, Queue <Effect> effects) { // If there are no effects then return a new sprite with the texture attached. if (effects.Count == 0) { return(texture); } // We are going to have to create a new RenderTarget2D, and then draw the texture multiple times on said render target in order to apply every effect. float x = texture.Width * 0.5f; float y = -texture.Height * 0.5f; Camera camera = new OrthographicCamera() .SetProjection(texture.Width, texture.Height, 0.5f, 2) .SetPosition(x, y, 1); // In order to apply multiple effects, and avoid weird visual artifacts, we need to create a RenderTarget2D for each effect. RenderTarget2D[] renderTargets = new RenderTarget2D[effects.Count]; for (int i = 0; i < renderTargets.Length; i++) { renderTargets[i] = new RenderTarget2D(graphicsDevice, texture.Width, texture.Height); } int totalEffects = effects.Count; for (int i = 0; i < totalEffects; i++) { graphicsDevice.SetRenderTarget(renderTargets[i]); graphicsDevice.Clear(Color.Transparent); Sprite sprite = new Sprite() { // The first pass starts with the initial texture. Every pass after that will use the last render target (which means the effects will accumulate). Texture = i == 0 ? texture : renderTargets[i - 1], RenderOptions = new RenderOptions() { Effect = effects.Dequeue() } }; Sketch.DrawSprite(sprite, camera); graphicsDevice.SetRenderTarget(null); } // Dispose all render targets except for the last one. for (int i = 0; i < renderTargets.Length - 1; i++) { renderTargets[i].Dispose(); } // We cannot dispose of the last render target just yet. Instead we are going to have to add it to a list, and deal with it later. Decomission(renderTargets[^ 1]);
static DebugManager() { camera = new OrthographicCamera() .SetProjection(WindowManager.WindowWidth, WindowManager.WindowHeight, 0.25f, 8); camera.SetPosition(WindowManager.WindowWidth * 0.5f, -WindowManager.WindowHeight * 0.5f, 1); WindowManager.WindowResize += HandleResize; font = AssetManager.GetFont("Relatus_Probity"); fontShader = new BMFontShader(); }
internal static void Draw() { graphicsDevice.Clear(Color.Black); float x = WindowManager.WindowWidth * 0.5f; float y = -WindowManager.WindowHeight * 0.5f; Camera camera = new OrthographicCamera() .SetProjection(WindowManager.WindowWidth, WindowManager.WindowHeight, 0.5f, 2) .SetPosition(x, y, 1); if (effects.Count == 0) { // Draw all the saved RenderTargets. Sketch.SpriteBatcher .AttachCamera(camera) .SetBatchExecution(batchExecution) .Begin() .AddRange(layers) .End(); } else { // We need flatten all the layers into a single layer. RenderTarget2D flatten = new RenderTarget2D(graphicsDevice, WindowManager.WindowWidth, WindowManager.WindowHeight); graphicsDevice.SetRenderTarget(flatten); graphicsDevice.Clear(Color.Transparent); Sketch.SpriteBatcher .AttachCamera(camera) .SetBatchExecution(batchExecution) .Begin() .AddRange(layers) .End(); graphicsDevice.SetRenderTarget(null); // Now that we have a single texture to work with we can apply all of the effects to said texture. Sprite sprite = new Sprite() { Texture = ApplyEffects(flatten, effects) }; Sketch.DrawSprite(sprite, camera); flatten.Dispose(); } // Clean up. for (int i = 0; i < decommissioned.Count; i++) { decommissioned[i].Dispose(); } for (int i = 0; i < layers.Count; i++) { layers[i].Texture.Dispose(); } decommissioned.Clear(); layers.Clear(); }