FpsCounter.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  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 PerformanceMeasuring.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. // Get debug manager from game service.
  43. debugManager =
  44. Game.Services.GetService(typeof(DebugManager)) as DebugManager;
  45. if (debugManager == null)
  46. throw new InvalidOperationException("DebugManaer is not registered.");
  47. // Register 'fps' command if debug command is registered as a service.
  48. IDebugCommandHost host =
  49. Game.Services.GetService(typeof(IDebugCommandHost))
  50. as IDebugCommandHost;
  51. if (host != null)
  52. {
  53. host.RegisterCommand("fps", "FPS Counter", this.CommandExecute);
  54. Visible = true;
  55. }
  56. // Initialize parameters.
  57. Fps = 0;
  58. sampleFrames = 0;
  59. stopwatch = Stopwatch.StartNew();
  60. stringBuilder.Length = 0;
  61. base.Initialize();
  62. }
  63. /// <summary>
  64. /// FPS command implementation.
  65. /// </summary>
  66. private void CommandExecute(IDebugCommandHost host,
  67. string command, IList<string> arguments)
  68. {
  69. if (arguments.Count == 0)
  70. Visible = !Visible;
  71. foreach (string arg in arguments)
  72. {
  73. switch (arg.ToLower())
  74. {
  75. case "on":
  76. Visible = true;
  77. break;
  78. case "off":
  79. Visible = false;
  80. break;
  81. }
  82. }
  83. }
  84. public override void Update(GameTime gameTime)
  85. {
  86. if (stopwatch.Elapsed > SampleSpan)
  87. {
  88. // Update FPS value and start next sampling period.
  89. Fps = (float)sampleFrames / (float)stopwatch.Elapsed.TotalSeconds;
  90. stopwatch.Reset();
  91. stopwatch.Start();
  92. sampleFrames = 0;
  93. // Update draw string.
  94. stringBuilder.Length = 0;
  95. stringBuilder.Append("FPS: ");
  96. stringBuilder.AppendNumber(Fps);
  97. }
  98. }
  99. public override void Draw(GameTime gameTime)
  100. {
  101. sampleFrames++;
  102. SpriteBatch spriteBatch = debugManager.SpriteBatch;
  103. SpriteFont font = debugManager.DebugFont;
  104. // Compute size of border area.
  105. Vector2 size = font.MeasureString("X");
  106. Rectangle rc =
  107. new Rectangle(0, 0, (int)(size.X * 14f), (int)(size.Y * 1.3f));
  108. Layout layout = new Layout(spriteBatch.GraphicsDevice.Viewport);
  109. rc = layout.Place(rc, 0.01f, 0.01f, Alignment.TopLeft);
  110. // Place FPS string in border area.
  111. size = font.MeasureString(stringBuilder);
  112. layout.ClientArea = rc;
  113. Vector2 pos = layout.Place(size, 0, 0.1f, Alignment.Center);
  114. // Draw
  115. spriteBatch.Begin();
  116. spriteBatch.Draw(debugManager.WhiteTexture, rc, new Color(0, 0, 0, 128));
  117. spriteBatch.DrawString(font, stringBuilder, pos, Color.White);
  118. spriteBatch.End();
  119. base.Draw(gameTime);
  120. }
  121. }
  122. }