Game.cs 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. #region File Description
  2. //-----------------------------------------------------------------------------
  3. // Game.cs
  4. //
  5. // Microsoft XNA Community Game Platform
  6. // Copyright (C) Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #endregion
  9. #region Using Statements
  10. using Microsoft.Xna.Framework;
  11. using Microsoft.Xna.Framework.Content;
  12. using Microsoft.Xna.Framework.Graphics;
  13. using Microsoft.Xna.Framework.Input;
  14. #endregion
  15. namespace BloomPostprocess
  16. {
  17. /// <summary>
  18. /// Sample showing how to implement a bloom postprocess,
  19. /// adding a glowing effect over the top of an existing scene.
  20. /// </summary>
  21. public class BloomPostprocessGame : Microsoft.Xna.Framework.Game
  22. {
  23. #region Fields
  24. GraphicsDeviceManager graphics;
  25. BloomComponent bloom;
  26. int bloomSettingsIndex = 0;
  27. SpriteBatch spriteBatch;
  28. SpriteFont spriteFont;
  29. Texture2D background;
  30. Model model;
  31. KeyboardState lastKeyboardState = new KeyboardState();
  32. GamePadState lastGamePadState = new GamePadState();
  33. KeyboardState currentKeyboardState = new KeyboardState();
  34. GamePadState currentGamePadState = new GamePadState();
  35. #endregion
  36. #region Initialization
  37. public BloomPostprocessGame()
  38. {
  39. Content.RootDirectory = "Content";
  40. graphics = new GraphicsDeviceManager(this);
  41. bloom = new BloomComponent(this);
  42. Components.Add(bloom);
  43. }
  44. /// <summary>
  45. /// Load your graphics content.
  46. /// </summary>
  47. protected override void LoadContent()
  48. {
  49. spriteBatch = new SpriteBatch(graphics.GraphicsDevice);
  50. spriteFont = Content.Load<SpriteFont>("hudFont");
  51. background = Content.Load<Texture2D>("sunset");
  52. model = Content.Load<Model>("tank");
  53. }
  54. #endregion
  55. #region Update and Draw
  56. /// <summary>
  57. /// Allows the game to run logic.
  58. /// </summary>
  59. protected override void Update(GameTime gameTime)
  60. {
  61. HandleInput();
  62. base.Update(gameTime);
  63. }
  64. /// <summary>
  65. /// This is called when the game should draw itself.
  66. /// </summary>
  67. protected override void Draw(GameTime gameTime)
  68. {
  69. GraphicsDevice device = graphics.GraphicsDevice;
  70. Viewport viewport = device.Viewport;
  71. bloom.BeginDraw();
  72. device.Clear(Color.Black);
  73. // Draw the background image.
  74. spriteBatch.Begin(0, BlendState.Opaque);
  75. spriteBatch.Draw(background,
  76. new Rectangle(0, 0, viewport.Width, viewport.Height),
  77. Color.White);
  78. spriteBatch.End();
  79. // Draw the spinning model.
  80. device.DepthStencilState = DepthStencilState.Default;
  81. DrawModel(gameTime);
  82. // Draw other components (which includes the bloom).
  83. base.Draw(gameTime);
  84. // Display some text over the top. Note how we draw this after the bloom,
  85. // because we don't want the text to be affected by the postprocessing.
  86. DrawOverlayText();
  87. }
  88. /// <summary>
  89. /// Helper for drawing the spinning 3D model.
  90. /// </summary>
  91. void DrawModel(GameTime gameTime)
  92. {
  93. float time = (float)gameTime.TotalGameTime.TotalSeconds;
  94. Viewport viewport = graphics.GraphicsDevice.Viewport;
  95. float aspectRatio = (float)viewport.Width / (float)viewport.Height;
  96. // Create camera matrices.
  97. Matrix world = Matrix.CreateRotationY(time * 0.42f);
  98. Matrix view = Matrix.CreateLookAt(new Vector3(750, 100, 0),
  99. new Vector3(0, 300, 0),
  100. Vector3.Up);
  101. Matrix projection = Matrix.CreatePerspectiveFieldOfView(1, aspectRatio,
  102. 1, 10000);
  103. // Look up the bone transform matrices.
  104. Matrix[] transforms = new Matrix[model.Bones.Count];
  105. model.CopyAbsoluteBoneTransformsTo(transforms);
  106. // Draw the model.
  107. foreach (ModelMesh mesh in model.Meshes)
  108. {
  109. foreach (BasicEffect effect in mesh.Effects)
  110. {
  111. effect.World = transforms[mesh.ParentBone.Index] * world;
  112. effect.View = view;
  113. effect.Projection = projection;
  114. effect.EnableDefaultLighting();
  115. // Override the default specular color to make it nice and bright,
  116. // so we'll get some decent glints that the bloom can key off.
  117. effect.SpecularColor = Vector3.One;
  118. }
  119. mesh.Draw();
  120. }
  121. }
  122. /// <summary>
  123. /// Displays an overlay showing what the controls are,
  124. /// and which settings are currently selected.
  125. /// </summary>
  126. void DrawOverlayText()
  127. {
  128. string text = "A = settings (" + bloom.Settings.Name + ")\n" +
  129. "B = toggle bloom (" + (bloom.Visible ? "on" : "off") + ")\n" +
  130. "X = show buffer (" + bloom.ShowBuffer.ToString() + ")";
  131. spriteBatch.Begin();
  132. // Draw the string twice to create a drop shadow, first colored black
  133. // and offset one pixel to the bottom right, then again in white at the
  134. // intended position. This makes text easier to read over the background.
  135. spriteBatch.DrawString(spriteFont, text, new Vector2(65, 65), Color.Black);
  136. spriteBatch.DrawString(spriteFont, text, new Vector2(64, 64), Color.White);
  137. spriteBatch.End();
  138. }
  139. #endregion
  140. #region Handle Input
  141. /// <summary>
  142. /// Handles input for quitting or changing the bloom settings.
  143. /// </summary>
  144. private void HandleInput()
  145. {
  146. lastKeyboardState = currentKeyboardState;
  147. lastGamePadState = currentGamePadState;
  148. currentKeyboardState = Keyboard.GetState();
  149. currentGamePadState = GamePad.GetState(PlayerIndex.One);
  150. // Check for exit.
  151. if (currentKeyboardState.IsKeyDown(Keys.Escape) ||
  152. currentGamePadState.Buttons.Back == ButtonState.Pressed)
  153. {
  154. Exit();
  155. }
  156. // Switch to the next bloom settings preset?
  157. if ((currentGamePadState.Buttons.A == ButtonState.Pressed &&
  158. lastGamePadState.Buttons.A != ButtonState.Pressed) ||
  159. (currentKeyboardState.IsKeyDown(Keys.A) &&
  160. lastKeyboardState.IsKeyUp(Keys.A)))
  161. {
  162. bloomSettingsIndex = (bloomSettingsIndex + 1) %
  163. BloomSettings.PresetSettings.Length;
  164. bloom.Settings = BloomSettings.PresetSettings[bloomSettingsIndex];
  165. bloom.Visible = true;
  166. }
  167. // Toggle bloom on or off?
  168. if ((currentGamePadState.Buttons.B == ButtonState.Pressed &&
  169. lastGamePadState.Buttons.B != ButtonState.Pressed) ||
  170. (currentKeyboardState.IsKeyDown(Keys.B) &&
  171. lastKeyboardState.IsKeyUp(Keys.B)))
  172. {
  173. bloom.Visible = !bloom.Visible;
  174. }
  175. // Cycle through the intermediate buffer debug display modes?
  176. if ((currentGamePadState.Buttons.X == ButtonState.Pressed &&
  177. lastGamePadState.Buttons.X != ButtonState.Pressed) ||
  178. (currentKeyboardState.IsKeyDown(Keys.X) &&
  179. lastKeyboardState.IsKeyUp(Keys.X)))
  180. {
  181. bloom.Visible = true;
  182. bloom.ShowBuffer++;
  183. if (bloom.ShowBuffer > BloomComponent.IntermediateBuffer.FinalResult)
  184. bloom.ShowBuffer= 0;
  185. }
  186. }
  187. #endregion
  188. }
  189. }