FpsCounter.cs 4.6 KB

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