FpsCounter.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. #region File Description
  2. //-----------------------------------------------------------------------------
  3. // FpsCounter.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 System;
  11. using System.Collections.Generic;
  12. using System.Diagnostics;
  13. using System.Text;
  14. using Microsoft.Xna.Framework;
  15. using Microsoft.Xna.Framework.Graphics;
  16. #endregion
  17. namespace HoneycombRush.GameDebugTools
  18. {
  19. /// <summary>
  20. /// Component for FPS measure and draw.
  21. /// </summary>
  22. public class FpsCounter : DrawableGameComponent
  23. {
  24. #region Properties
  25. /// <summary>
  26. /// Gets current FPS
  27. /// </summary>
  28. public float Fps { get; private set; }
  29. /// <summary>
  30. /// Gets/Sets FPS sample duration.
  31. /// </summary>
  32. public TimeSpan SampleSpan { get; set; }
  33. #endregion
  34. #region Fields
  35. // Reference for debug manager.
  36. private DebugManager debugManager;
  37. // Stopwatch for fps measuring.
  38. private Stopwatch stopwatch;
  39. private int sampleFrames;
  40. // stringBuilder for FPS counter draw.
  41. private StringBuilder stringBuilder = new StringBuilder(16);
  42. #endregion
  43. #region Initialize
  44. public FpsCounter(Game game)
  45. : base(game)
  46. {
  47. SampleSpan = TimeSpan.FromSeconds(1);
  48. }
  49. public override void Initialize()
  50. {
  51. DrawOrder = int.MaxValue - 1;
  52. // Get debug manager from game service.
  53. debugManager =
  54. Game.Services.GetService(typeof(DebugManager)) as DebugManager;
  55. if (debugManager == null)
  56. throw new InvalidOperationException("DebugManaer is not registered.");
  57. // Register 'fps' command if debug command is registered as a service.
  58. IDebugCommandHost host =
  59. Game.Services.GetService(typeof(IDebugCommandHost))
  60. as IDebugCommandHost;
  61. if (host != null)
  62. {
  63. host.RegisterCommand("fps", "FPS Counter", this.CommandExecute);
  64. Visible = false;
  65. }
  66. // Initialize parameters.
  67. Fps = 0;
  68. sampleFrames = 0;
  69. stopwatch = Stopwatch.StartNew();
  70. stringBuilder.Length = 0;
  71. base.Initialize();
  72. }
  73. #endregion
  74. /// <summary>
  75. /// FPS command implementation.
  76. /// </summary>
  77. private void CommandExecute(IDebugCommandHost host,
  78. string command, IList<string> arguments)
  79. {
  80. if (arguments.Count == 0)
  81. Visible = !Visible;
  82. foreach (string arg in arguments)
  83. {
  84. switch (arg.ToLower())
  85. {
  86. case "on":
  87. Visible = true;
  88. break;
  89. case "off":
  90. Visible = false;
  91. break;
  92. }
  93. }
  94. }
  95. #region Update and Draw
  96. public override void Update(GameTime gameTime)
  97. {
  98. if (stopwatch.Elapsed > SampleSpan)
  99. {
  100. // Update FPS value and start next sampling period.
  101. Fps = (float)sampleFrames / (float)stopwatch.Elapsed.TotalSeconds;
  102. stopwatch.Reset();
  103. stopwatch.Start();
  104. sampleFrames = 0;
  105. // Update draw string.
  106. stringBuilder.Length = 0;
  107. stringBuilder.Append("FPS: ");
  108. stringBuilder.AppendNumber(Fps);
  109. }
  110. }
  111. public override void Draw(GameTime gameTime)
  112. {
  113. sampleFrames++;
  114. SpriteBatch spriteBatch = debugManager.SpriteBatch;
  115. SpriteFont font = debugManager.DebugFont;
  116. // Compute size of border area.
  117. Vector2 size = font.MeasureString("X");
  118. Rectangle rc =
  119. new Rectangle(0, 0, (int)(size.X * 14f), (int)(size.Y * 1.3f));
  120. Layout layout = new Layout(spriteBatch.GraphicsDevice.Viewport);
  121. rc = layout.Place(rc, 0.01f, 0.01f, Alignment.TopLeft);
  122. // Place FPS string in border area.
  123. size = font.MeasureString(stringBuilder);
  124. layout.ClientArea = rc;
  125. Vector2 pos = layout.Place(size, 0, 0.1f, Alignment.Center);
  126. // Draw
  127. spriteBatch.Begin();
  128. spriteBatch.Draw(debugManager.WhiteTexture, rc, new Color(0, 0, 0, 128));
  129. spriteBatch.DrawString(font, stringBuilder, pos, Color.White);
  130. spriteBatch.End();
  131. base.Draw(gameTime);
  132. }
  133. #endregion
  134. }
  135. }