PostScreenMenu.cs 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. //-----------------------------------------------------------------------------
  2. // PostScreenMenu.cs
  3. //
  4. // Microsoft XNA Community Game Platform
  5. // Copyright (C) Microsoft Corporation. All rights reserved.
  6. //-----------------------------------------------------------------------------
  7. using Microsoft.Xna.Framework;
  8. using Microsoft.Xna.Framework.Graphics;
  9. using Microsoft.Xna.Framework.Input;
  10. using System;
  11. using System.Collections;
  12. using System.IO;
  13. using System.Text;
  14. using RacingGame.GameLogic;
  15. using RacingGame.Graphics;
  16. using RacingGame.Helpers;
  17. using Texture = RacingGame.Graphics.Texture;
  18. namespace RacingGame.Shaders
  19. {
  20. /// <summary>
  21. /// Post screen glow shader based on PostScreenMenu.fx
  22. /// </summary>
  23. /// <returns>Shader effect</returns>
  24. public class PostScreenMenu : ShaderEffect
  25. {
  26. /// <summary>
  27. /// The shader effect filename for this shader.
  28. /// </summary>
  29. private const string Filename = "PostScreenMenu.fx";
  30. /// <summary>
  31. /// Effect handles for window size and scene map.
  32. /// </summary>
  33. protected EffectParameter windowSize,
  34. sceneMap,
  35. downsampleMap,
  36. blurMap1,
  37. blurMap2,
  38. noiseMap,
  39. timer;
  40. /// <summary>
  41. /// Links to the passTextures, easier to write code this way.
  42. /// This are just reference copies. Static to load them only once
  43. /// (used for both PostScreenMenu and PostScreenGlow).
  44. /// </summary>
  45. //dunno why, but RenderToTexture crashes if we do this:
  46. protected static RenderToTexture sceneMapTexture,
  47. // Instead load twice:
  48. //protected RenderToTexture sceneMapTexture = null,
  49. downsampleMapTexture,
  50. blurMap1Texture,
  51. blurMap2Texture;
  52. /// <summary>
  53. /// Helper texture for the noise and film effects.
  54. /// </summary>
  55. private Texture noiseMapTexture = null;
  56. /// <summary>
  57. /// Is this post screen shader started?
  58. /// Else don't execute Show if it is called.
  59. /// </summary>
  60. protected static bool started = false;
  61. /// <summary>
  62. /// Started
  63. /// </summary>
  64. /// <returns>Bool</returns>
  65. public static bool Started
  66. {
  67. get
  68. {
  69. return started;
  70. }
  71. }
  72. /// <summary>
  73. /// Create post screen menu. Also used for the constructor of
  74. /// PostScreenGlow (same RenderToTextures used there).
  75. /// </summary>
  76. protected PostScreenMenu(string shaderFilename)
  77. : base(shaderFilename)
  78. {
  79. // Scene map texture
  80. if (sceneMapTexture == null)
  81. sceneMapTexture = new RenderToTexture(
  82. RenderToTexture.SizeType.FullScreen);
  83. // Downsample map texture (to 1/4 of the screen)
  84. if (downsampleMapTexture == null)
  85. downsampleMapTexture = new RenderToTexture(
  86. RenderToTexture.SizeType.QuarterScreen);
  87. // Blur map texture
  88. if (blurMap1Texture == null)
  89. blurMap1Texture = new RenderToTexture(
  90. RenderToTexture.SizeType.QuarterScreen);
  91. // Blur map texture
  92. if (blurMap2Texture == null)
  93. blurMap2Texture = new RenderToTexture(
  94. RenderToTexture.SizeType.QuarterScreen);
  95. }
  96. /// <summary>
  97. /// Create post screen menu
  98. /// </summary>
  99. public PostScreenMenu()
  100. : this(Filename)
  101. {
  102. }
  103. /// <summary>
  104. /// Reload
  105. /// </summary>
  106. protected override void GetParameters()
  107. {
  108. // Can't get parameters if loading failed!
  109. if (effect == null)
  110. return;
  111. windowSize = effect.Parameters["windowSize"];
  112. sceneMap = effect.Parameters["sceneMap"];
  113. // We need both windowSize and sceneMap.
  114. if (windowSize == null ||
  115. sceneMap == null)
  116. throw new NotSupportedException("windowSize and sceneMap must be " +
  117. "valid in PostScreenShader=" + Filename);
  118. // Init additional stuff
  119. downsampleMap = effect.Parameters["downsampleMap"];
  120. blurMap1 = effect.Parameters["blurMap1"];
  121. blurMap2 = effect.Parameters["blurMap2"];
  122. timer = effect.Parameters["Timer"];
  123. // Load noise texture for stripes effect
  124. noiseMap = effect.Parameters["noiseMap"];
  125. noiseMapTexture = new Texture("Noise128x128");
  126. // Set texture
  127. noiseMap.SetValue(noiseMapTexture.XnaTexture);
  128. }
  129. /// <summary>
  130. /// Start this post screen shader, will just call SetRenderTarget.
  131. /// All render calls will now be drawn on the sceneMapTexture.
  132. /// Make sure you don't reset the RenderTarget until you call Show()!
  133. /// </summary>
  134. public void Start()
  135. {
  136. // Only apply post screen shader if texture is valid and effect is valid
  137. if (sceneMapTexture == null ||
  138. effect == null ||
  139. started == true ||
  140. // Also skip if we don't use post screen shaders at all!
  141. BaseGame.UsePostScreenShaders == false)
  142. return;
  143. BaseGame.SetRenderTarget(sceneMapTexture.RenderTarget, true);
  144. started = true;
  145. }
  146. /// <summary>
  147. /// Execute shaders and show result on screen, Start(..) must have been
  148. /// called before and the scene should be rendered to sceneMapTexture.
  149. /// </summary>
  150. public virtual void Show()
  151. {
  152. // Only apply post screen glow if texture is valid and effect is valid
  153. if (sceneMapTexture == null ||
  154. Valid == false ||
  155. started == false)
  156. return;
  157. started = false;
  158. // Resolve sceneMapTexture render target for Xbox360 support
  159. sceneMapTexture.Resolve();
  160. // Don't use or write to the z buffer
  161. BaseGame.Device.DepthStencilState = DepthStencilState.None;
  162. // Also don't use any kind of blending.
  163. BaseGame.Device.BlendState = BlendState.Opaque;
  164. if (windowSize != null)
  165. windowSize.SetValue(
  166. new Vector2(sceneMapTexture.Width, sceneMapTexture.Height));
  167. if (sceneMap != null)
  168. sceneMap.SetValue(sceneMapTexture.XnaTexture);
  169. if (timer != null)
  170. // Add a little offset to prevent first effect.
  171. timer.SetValue(BaseGame.TotalTime + 0.75f);
  172. effect.CurrentTechnique = effect.Techniques["ScreenGlow20"];
  173. // We must have exactly 4 passes!
  174. if (effect.CurrentTechnique.Passes.Count != 4)
  175. throw new InvalidOperationException(
  176. "This shader should have exactly 4 passes!");
  177. try
  178. {
  179. for (int pass = 0; pass < effect.CurrentTechnique.Passes.Count; pass++)
  180. {
  181. if (pass == 0)
  182. downsampleMapTexture.SetRenderTarget();
  183. else if (pass == 1)
  184. blurMap1Texture.SetRenderTarget();
  185. else if (pass == 2)
  186. blurMap2Texture.SetRenderTarget();
  187. else
  188. {
  189. BaseGame.ResetRenderTarget(true);
  190. }
  191. EffectPass effectPass = effect.CurrentTechnique.Passes[pass];
  192. effectPass.Apply();
  193. VBScreenHelper.Render();
  194. if (pass == 0)
  195. {
  196. downsampleMapTexture.Resolve();
  197. if (downsampleMap != null)
  198. downsampleMap.SetValue(downsampleMapTexture.XnaTexture);
  199. effectPass.Apply();
  200. }
  201. else if (pass == 1)
  202. {
  203. blurMap1Texture.Resolve();
  204. if (blurMap1 != null)
  205. blurMap1.SetValue(blurMap1Texture.XnaTexture);
  206. effectPass.Apply();
  207. }
  208. else if (pass == 2)
  209. {
  210. blurMap2Texture.Resolve();
  211. if (blurMap2 != null)
  212. blurMap2.SetValue(blurMap2Texture.XnaTexture);
  213. effectPass.Apply();
  214. }
  215. }
  216. }
  217. finally
  218. {
  219. // Restore z buffer state
  220. BaseGame.Device.DepthStencilState = DepthStencilState.Default;
  221. }
  222. }
  223. }
  224. }