#region File Description
//-----------------------------------------------------------------------------
// Game.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion
#region Using Statements
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
#endregion
namespace BloomPostprocess
{
///
/// Sample showing how to implement a bloom postprocess,
/// adding a glowing effect over the top of an existing scene.
///
public class BloomPostprocessGame : Microsoft.Xna.Framework.Game
{
#region Fields
GraphicsDeviceManager graphics;
BloomComponent bloom;
int bloomSettingsIndex = 0;
SpriteBatch spriteBatch;
SpriteFont spriteFont;
Texture2D background;
Model model;
KeyboardState lastKeyboardState = new KeyboardState();
GamePadState lastGamePadState = new GamePadState();
KeyboardState currentKeyboardState = new KeyboardState();
GamePadState currentGamePadState = new GamePadState();
#endregion
#region Initialization
public BloomPostprocessGame()
{
Content.RootDirectory = "Content";
graphics = new GraphicsDeviceManager(this);
bloom = new BloomComponent(this);
Components.Add(bloom);
}
///
/// Load your graphics content.
///
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(graphics.GraphicsDevice);
spriteFont = Content.Load("hudFont");
background = Content.Load("sunset");
model = Content.Load("tank");
}
#endregion
#region Update and Draw
///
/// Allows the game to run logic.
///
protected override void Update(GameTime gameTime)
{
HandleInput();
base.Update(gameTime);
}
///
/// This is called when the game should draw itself.
///
protected override void Draw(GameTime gameTime)
{
GraphicsDevice device = graphics.GraphicsDevice;
Viewport viewport = device.Viewport;
bloom.BeginDraw();
device.Clear(Color.Black);
// Draw the background image.
spriteBatch.Begin(0, BlendState.Opaque);
spriteBatch.Draw(background,
new Rectangle(0, 0, viewport.Width, viewport.Height),
Color.White);
spriteBatch.End();
// Draw the spinning model.
device.DepthStencilState = DepthStencilState.Default;
DrawModel(gameTime);
// Draw other components (which includes the bloom).
base.Draw(gameTime);
// Display some text over the top. Note how we draw this after the bloom,
// because we don't want the text to be affected by the postprocessing.
DrawOverlayText();
}
///
/// Helper for drawing the spinning 3D model.
///
void DrawModel(GameTime gameTime)
{
float time = (float)gameTime.TotalGameTime.TotalSeconds;
Viewport viewport = graphics.GraphicsDevice.Viewport;
float aspectRatio = (float)viewport.Width / (float)viewport.Height;
// Create camera matrices.
Matrix world = Matrix.CreateRotationY(time * 0.42f);
Matrix view = Matrix.CreateLookAt(new Vector3(750, 100, 0),
new Vector3(0, 300, 0),
Vector3.Up);
Matrix projection = Matrix.CreatePerspectiveFieldOfView(1, aspectRatio,
1, 10000);
// Look up the bone transform matrices.
Matrix[] transforms = new Matrix[model.Bones.Count];
model.CopyAbsoluteBoneTransformsTo(transforms);
// Draw the model.
foreach (ModelMesh mesh in model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.World = transforms[mesh.ParentBone.Index] * world;
effect.View = view;
effect.Projection = projection;
effect.EnableDefaultLighting();
// Override the default specular color to make it nice and bright,
// so we'll get some decent glints that the bloom can key off.
effect.SpecularColor = Vector3.One;
}
mesh.Draw();
}
}
///
/// Displays an overlay showing what the controls are,
/// and which settings are currently selected.
///
void DrawOverlayText()
{
string text = "A = settings (" + bloom.Settings.Name + ")\n" +
"B = toggle bloom (" + (bloom.Visible ? "on" : "off") + ")\n" +
"X = show buffer (" + bloom.ShowBuffer.ToString() + ")";
spriteBatch.Begin();
// Draw the string twice to create a drop shadow, first colored black
// and offset one pixel to the bottom right, then again in white at the
// intended position. This makes text easier to read over the background.
spriteBatch.DrawString(spriteFont, text, new Vector2(65, 65), Color.Black);
spriteBatch.DrawString(spriteFont, text, new Vector2(64, 64), Color.White);
spriteBatch.End();
}
#endregion
#region Handle Input
///
/// Handles input for quitting or changing the bloom settings.
///
private void HandleInput()
{
lastKeyboardState = currentKeyboardState;
lastGamePadState = currentGamePadState;
currentKeyboardState = Keyboard.GetState();
currentGamePadState = GamePad.GetState(PlayerIndex.One);
// Check for exit.
if (currentKeyboardState.IsKeyDown(Keys.Escape) ||
currentGamePadState.Buttons.Back == ButtonState.Pressed)
{
Exit();
}
// Switch to the next bloom settings preset?
if ((currentGamePadState.Buttons.A == ButtonState.Pressed &&
lastGamePadState.Buttons.A != ButtonState.Pressed) ||
(currentKeyboardState.IsKeyDown(Keys.A) &&
lastKeyboardState.IsKeyUp(Keys.A)))
{
bloomSettingsIndex = (bloomSettingsIndex + 1) %
BloomSettings.PresetSettings.Length;
bloom.Settings = BloomSettings.PresetSettings[bloomSettingsIndex];
bloom.Visible = true;
}
// Toggle bloom on or off?
if ((currentGamePadState.Buttons.B == ButtonState.Pressed &&
lastGamePadState.Buttons.B != ButtonState.Pressed) ||
(currentKeyboardState.IsKeyDown(Keys.B) &&
lastKeyboardState.IsKeyUp(Keys.B)))
{
bloom.Visible = !bloom.Visible;
}
// Cycle through the intermediate buffer debug display modes?
if ((currentGamePadState.Buttons.X == ButtonState.Pressed &&
lastGamePadState.Buttons.X != ButtonState.Pressed) ||
(currentKeyboardState.IsKeyDown(Keys.X) &&
lastKeyboardState.IsKeyUp(Keys.X)))
{
bloom.Visible = true;
bloom.ShowBuffer++;
if (bloom.ShowBuffer > BloomComponent.IntermediateBuffer.FinalResult)
bloom.ShowBuffer= 0;
}
}
#endregion
}
}