public PostFilter(Shader shader) { if (shader is PostShader) { this.shader = (PostShader)shader; } else { throw new Exception("Must be of type PostShader!"); } }
/// <summary> /// Applies a <see cref="PostShader"/> to the <see cref="OmegaEngine.Graphics.RenderTarget"/> and outputs the result to the back-buffer /// </summary> /// <param name="shader">The <see cref="PostShader"/> to apply</param> /// <param name="alpha">The level of transparency from 0 (solid) to 255 (invisible)</param> private void ShaderToBackBuffer(PostShader shader, int alpha) { Engine.State.AlphaBlend = alpha; using (new ProfilerEvent(() => "Apply " + shader)) { shader.Apply(delegate { Engine.Device.BeginScene(); Engine.DrawQuadShader(); Engine.Device.EndScene(); }, _area.Size, shader.OverlayRendering ? null : RenderTarget); } }
/// <summary> /// Updates the <see cref="OmegaEngine.Graphics.RenderTarget"/> using a <see cref="PostShader"/> /// </summary> /// <param name="shader">The <see cref="PostShader"/> to apply</param> protected void ShaderToRenderTarget(PostShader shader) { #region Sanity checks if (shader == null) { throw new ArgumentNullException(nameof(shader)); } #endregion // Make sure input and output texture aren't the same var sceneMap = RenderTarget; if (!shader.OverlayRendering) { SwapRenderTarget(); } // Apply the shader and move data from one texture to the other using (new ProfilerEvent(() => "Apply " + shader)) shader.Apply(() => RenderTarget.RenderTo(Engine.DrawQuadShader), sceneMap.Size, shader.OverlayRendering ? null : sceneMap); }
/// <summary> /// Applies an intermediate shader from <see cref="PostShaders"/> to the output. /// </summary> /// <param name="shader">The shader to apply.</param> /// <param name="sceneOnBackBuffer"> /// Is the scene currently on the backbuffer?<br/> /// If this is <c>false</c>, it is in <see cref="RenderTarget"/>. /// </param> private void ApplyPostShaderIntermediate(PostShader shader, ref bool sceneOnBackBuffer) { if (sceneOnBackBuffer && shader.OverlayRendering) { // Apply the shader directly on the back-buffer ShaderToBackBuffer(shader, 0); } else { // Make sure the scene is inside a texture if (sceneOnBackBuffer) { CopyBackBufferToTexture(); sceneOnBackBuffer = false; } // Update the RenderTarget texture to incorporate the PostShader effect ShaderToRenderTarget(shader); } }
/// <summary> /// Applies the last shader from <see cref="PostShaders"/> to the output. /// </summary> /// <param name="shader">The shader to apply.</param> /// <param name="sceneOnBackBuffer"> /// Is the scene currently on the backbuffer?<br/> /// If this is <c>false</c>, it is in <see cref="RenderTarget"/>. /// </param> private void ApplyPostShaderLast(PostShader shader, ref bool sceneOnBackBuffer) { if (FullAlpha == 0) { // Opaque // Scene must be on the back-buffer before using a shader with overlay rendering if (shader.OverlayRendering && !sceneOnBackBuffer) { OutputRenderTarget(0); } // Make sure the scene ends up in a texture (out of the back-buffer) if (!shader.OverlayRendering && sceneOnBackBuffer) { CopyBackBufferToTexture(); sceneOnBackBuffer = false; } // Apply the shader directly on the back-buffer ShaderToBackBuffer(shader, 0); } else { // Transparent Debug.Assert(!sceneOnBackBuffer, "Scene should never be on back-buffer with alpha-blended output"); if (shader.OverlayRendering) { // Update the RenderTarget texture to incorporate the PostShader effect and then output it ShaderToRenderTarget(shader); OutputRenderTarget(FullAlpha); } else { // Apply the shader while outputing to a transparent quad ShaderToBackBuffer(shader, FullAlpha); } } }