XNA 4.0以50而不是60 fps运行

时间:2010-10-07 01:35:13

标签: xna frame-rate xna-4.0

我正在尝试使用XNA 4.0,按照教程和创建非常基本的东西(如三角形和一些线条;-))。在这样做时,我注意到我的所有应用程序都不会超过50-51 fps(使用Fraps)。这并不是说我在慢速计算机或显卡(Ati HD4870)上运行繁重的程序,它必须与XNA有关(游戏在这里运行得很好)。

现在,我读到的有关XNA的所有内容都表示默认更新频率是每秒60次,我想得到它。

  • 全屏显示与窗口相同
  • 如果我将SynchronizeWithVerticalRetrace设置为false或true:same
  • 如果没有Visual Studio运行程序,我只能获得41 fps
  • 当我使用TargetElapsedTime = new TimeSpan(0, 0, 0, 0, 10);覆盖更新频率时,fps会显着上升。我注意到这仍然是不正确的:10意味着10毫秒,但我只“获得83 fps而不是100。在1毫秒我获得850 fps。因此,我获得的fps和我应该获得的内容的偏差是非常一致的。在我看来,时机上有问题吗?

任何人都知道这里可能存在什么问题和/或有建议获得稳定的60 fps?

谢谢!

2 个答案:

答案 0 :(得分:4)

FRAPS不能给你准确的结果吗?您是否尝试在游戏中添加自己的帧率计数器并查看这些结果所说的内容? Shawn Hargreaves有一个他在博客上编码的方法,添加到一个新的空白XNA游戏项目应该是非常轻松的。

http://blogs.msdn.com/b/shawnhar/archive/2007/06/08/displaying-the-framerate.aspx

当您自己进行计算时,您是否看到相同的FPS或报告方式不同?

答案 1 :(得分:1)

我在XNA 4上放了以下代码,它的锁定速度为60 fps。在你的系统上尝试一下(你只需添加适当的精灵字体),看看你是否也得到60 fps。如果是这样,请将调整问题放入问题代码中,看看是否得到相同的结果。

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace _60fps
{
public class Game1 : Microsoft.Xna.Framework.Game
{
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;
    SpriteFont OutputFont;
    float Fps = 0f;
    private const int NumberSamples = 50; //Update fps timer based on this number of samples
    int[] Samples = new int[NumberSamples];
    int CurrentSample = 0;
    int TicksAggregate = 0;
    int SecondSinceStart = 0;

    public Game1()
    {
        graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";
    }

    protected override void Initialize()
    {
        base.Initialize();
        graphics.SynchronizeWithVerticalRetrace = false;
        int DesiredFrameRate = 60;
        TargetElapsedTime = new TimeSpan(TimeSpan.TicksPerSecond / DesiredFrameRate);
    }

    protected override void LoadContent()
    {
        spriteBatch = new SpriteBatch(GraphicsDevice);
        OutputFont = Content.Load<SpriteFont>("MessageFont");
    }

    protected override void UnloadContent()
    {/* Nothing to do */}

    protected override void Update(GameTime gameTime)
    {
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.Escape))
            this.Exit();

        base.Update(gameTime);
    }

    private float Sum(int[] Samples)
    {
        float RetVal = 0f;
        for (int i = 0; i < Samples.Length; i++)
        {
            RetVal += (float)Samples[i];
        }
        return RetVal;
    }

    private Color ClearColor = Color.FromNonPremultiplied(20, 20, 40, 255);
    protected override void Draw(GameTime gameTime)
    {
        Samples[CurrentSample++] = (int)gameTime.ElapsedGameTime.Ticks;
        TicksAggregate += (int)gameTime.ElapsedGameTime.Ticks;
        if (TicksAggregate > TimeSpan.TicksPerSecond)
        {
            TicksAggregate -= (int)TimeSpan.TicksPerSecond;
            SecondSinceStart += 1;
        }
        if (CurrentSample == NumberSamples) //We are past the end of the array since the array is 0-based and NumberSamples is 1-based
        {
            float AverageFrameTime = Sum(Samples) / NumberSamples;
            Fps = TimeSpan.TicksPerSecond / AverageFrameTime;
            CurrentSample = 0;
        }

        GraphicsDevice.Clear(ClearColor);
        spriteBatch.Begin();
        if (Fps > 0)
        {
            spriteBatch.DrawString(OutputFont, string.Format("Current FPS: {0}\r\nTime since startup: {1}", Fps.ToString("000"), TimeSpan.FromSeconds(SecondSinceStart).ToString()), new Vector2(10,10), Color.White);
        }
        spriteBatch.End();
        base.Draw(gameTime);
    }
}
}