topical media & game development
game-xna-intro-XnaShooterSoundProject-Shaders-PostScreenDarkenBorder.cs / cs
// Project: XnaGraphicEngine, File: PostScreenMenu.cs
// Namespace: XnaGraphicEngine.Shaders, Class: PostScreenMenu
// Path: C:\code\XnaGraphicEngine\Shaders, Author: Abi
// Code lines: 369, Size of file: 10,70 KB
// Creation date: 27.09.2006 03:46
// Last modified: 15.10.2006 19:59
// Generated with Commenter by abi.exDream.com
#region Using directives
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;
using System.Collections;
using System.IO;
using System.Text;
using XnaGraphicEngine.Game;
using XnaGraphicEngine.Graphics;
using XnaGraphicEngine.Helpers;
using Texture = XnaGraphicEngine.Graphics.Texture;
using Model = XnaGraphicEngine.Graphics.Model;
#endregion
namespace XnaGraphicEngine.Shaders
{
<summary>
Post screen glow shader based on PostScreenMenu.fx
</summary>
<returns>Shader effect
</returns>
public class PostScreenDarkenBorder : ShaderEffect
{
#region Variables
<summary>
The shader effect filename for this shader.
</summary>
private const string Filename = "PostScreenDarkenBorder.fx";
<summary>
Effect handles for window size and scene map.
</summary>
protected EffectParameter windowSize,
sceneMap,
screenBorderFadeoutMap;
<summary>
Links to the passTextures, easier to write code this way.
This are just reference copies. Static to load them only once
(used for both PostScreenMenu and PostScreenGlow).
</summary>
protected static RenderToTexture sceneMapTexture;
<summary>
Helper texture for the screen border (darken the borders).
</summary>
private Texture screenBorderFadeoutMapTexture = null;
<summary>
Is this post screen shader started?
Else don't execute Show if it is called.
</summary>
protected static bool started = false;
<summary>
Started
</summary>
<returns>Bool
</returns>
public bool Started
{
get
{
return started;
} // get
} // Started
#endregion
#region Constructor
<summary>
Create post screen menu. Also used for the constructor of
PostScreenGlow (same RenderToTextures used there).
</summary>
protected PostScreenDarkenBorder(string shaderFilename)
: base(shaderFilename)
{
Load();
} // PostScreenDarkenBorder()
<summary>
Create post screen menu
</summary>
public PostScreenDarkenBorder()
: this(Filename)
{
} // PostScreenDarkenBorder()
#endregion
#region Dispose
<summary>
Dispose
</summary>
public override void Dispose()
{
base.Dispose();
if (sceneMapTexture != null)
sceneMapTexture.Dispose();
sceneMapTexture = null;
} // Dispose()
#endregion
#region Load
<summary>
Load in case the device got lost.
</summary>
public override void Load()
{
base.Load();
// Scene map texture
if (sceneMapTexture == null)
sceneMapTexture = new RenderToTexture(
RenderToTexture.SizeType.FullScreen);
} // Load()
#endregion
#region Get parameters
<summary>
Reload
</summary>
protected override void GetParameters()
{
// Can't get parameters if loading failed!
if (effect == null)
return;
windowSize = effect.Parameters["windowSize"];
sceneMap = effect.Parameters["sceneMap"];
// We need both windowSize and sceneMap.
if (windowSize == null ||
sceneMap == null)
throw new NotSupportedException("windowSize and sceneMap must be " +
"valid in PostScreenShader=" + Filename);
// Load screen border texture
screenBorderFadeoutMap = effect.Parameters["screenBorderFadeoutMap"];
screenBorderFadeoutMapTexture = new Texture("ScreenBorderFadeout.dds");
// Set texture
screenBorderFadeoutMap.SetValue(
screenBorderFadeoutMapTexture.XnaTexture);
} // GetParameters()
#endregion
#region Start
<summary>
Start this post screen shader, will just call SetRenderTarget.
All render calls will now be drawn on the sceneMapTexture.
Make sure you don't reset the RenderTarget until you call Show()!
</summary>
public void Start()
{
// Only apply post screen shader if texture is valid and effect is valid
if (sceneMapTexture == null ||
effect == null ||
started == true ||
// Also skip if we don't use post screen shaders at all!
BaseGame.UsePostScreenShaders == false)
return;
BaseGame.SetRenderTarget(sceneMapTexture.RenderTarget, true);
started = true;
} // Start()
#endregion
#region Show
<summary>
Execute shaders and show result on screen, Start(..) must have been
called before and the scene should be rendered to sceneMapTexture.
</summary>
public virtual void Show()
{
// Only apply post screen glow if texture is valid and effect is valid
if (sceneMapTexture == null ||
Valid == false ||
started == false)
return;
started = false;
// Resolve sceneMapTexture render target for Xbox360 support
sceneMapTexture.Resolve();
try
{
// Don't use or write to the z buffer
BaseGame.Device.RenderState.DepthBufferEnable = false;
BaseGame.Device.RenderState.DepthBufferWriteEnable = false;
// Also don't use any kind of blending.
BaseGame.Device.RenderState.AlphaBlendEnable = false;
//unused: BaseGame.Device.RenderState.Lighting = false;
if (windowSize != null)
windowSize.SetValue(new float[]
{ sceneMapTexture.Width, sceneMapTexture.Height });
if (sceneMap != null)
sceneMap.SetValue(sceneMapTexture.XnaTexture);
effect.CurrentTechnique = effect.Techniques["ScreenDarkenBorder"];
// We must have exactly 1 pass!
if (effect.CurrentTechnique.Passes.Count != 1)
throw new Exception("This shader should have exactly 1 pass!");
effect.Begin();
for (int pass = 0; pass < effect.CurrentTechnique.Passes.Count; pass++)
{
if (pass == 0)
// Do a full reset back to the back buffer
BaseGame.ResetRenderTarget(true);
EffectPass effectPass = effect.CurrentTechnique.Passes[pass];
effectPass.Begin();
//tst for last pass? VBScreenHelper.Render10x10Grid();
VBScreenHelper.Render();
effectPass.End();
} // for (pass, <, ++)
} // try
catch (Exception ex)
{
// Make effect invalid, continue rendering without this
// post screen shader.
effect = null;
BaseGame.ResetRenderTarget(true);
if DEBUG
throw ex;
else
Log.Write("Failed to render post screen shader "+Filename+": "+
ex.ToString());
endif
} // catch
finally
{
effect.End();
// Restore z buffer state
BaseGame.Device.RenderState.DepthBufferEnable = true;
BaseGame.Device.RenderState.DepthBufferWriteEnable = true;
} // finally
} // Show()
#endregion
#region Unit Testing
if DEBUG
<summary>
Test PostScreenDarkenBorder
</summary>
//
[Test]
public static void TestPostScreenDarkenBorder()
{
PreScreenSkyCubeMapping skyCube = null;
Model testModel = null;
PostScreenDarkenBorder postScreenShader = null;
TestGame.Start("TestPostScreenDarkenBorder",
delegate
{
skyCube = new PreScreenSkyCubeMapping();
testModel = new Model("Asteroid4");
postScreenShader = new PostScreenDarkenBorder();
},
delegate
{
// Start post screen shader to render everything to our sceneMap
if (Input.Keyboard[Keys.Space] == KeyState.Up &&
Input.GamePadBPressed == false)
postScreenShader.Start();
// Draw background sky cube
skyCube.RenderSky();
// And our testModel (the asteroid)
testModel.Render(Matrix.CreateScale(10));
// And finally show post screen shader
if (Input.Keyboard[Keys.Space] == KeyState.Up &&
Input.GamePadBPressed == false)
postScreenShader.Show();
TextureFont.WriteText(2, 30,
"Press space or B to disable post screen shader");
TextureFont.WriteText(2, 60,
"Press A to show sceneMap of post screen shader");
TextureFont.WriteText(2, 90,
"Speed Mode");
if (Input.Keyboard.IsKeyDown(Keys.A) ||
Input.GamePadAPressed)
{
sceneMapTexture.RenderOnScreen(
new Rectangle(10, 10, 256, 256));
} // if (Input.Keyboard.IsKeyDown)
//*/
});
} // TestPostScreenMenu()
endif
#endregion
} // class PostScreenDarkenBorder
} // namespace XnaGraphicEngine.Shaders
(C) Æliens
20/2/2008
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.