XNA 4.0 работает со скоростью 50 вместо 60 кадров в секунду

Я немного экспериментирую с XNA 4.0, следую руководствам и создаю очень простые вещи (например, треугольник и несколько линий ;-)). При этом я заметил, что все мои приложения никогда не работают со скоростью более 50-51 кадров в секунду (с Fraps). Дело не в том, что я запускаю тяжелые программы на медленном компьютере или видеокарте (Ati HD4870), это должно иметь какое-то отношение к XNA (игры здесь отлично работают).

Все, что я читал о XNA, говорит, что частота обновления по умолчанию составляет 60 раз в секунду, и я бы хотел это получить.

  • В полноэкранном режиме то же самое, что и в оконном.
  • Если я установил для SynchronizeWithVerticalRetrace значение false или true: то же самое
  • Если запустить программу без Visual Studio, я получаю только 41 кадр / с.
  • Когда я переопределяю частоту обновления, используя TargetElapsedTime = new TimeSpan(0, 0, 0, 0, 10);, частота кадров в секунду значительно возрастает. Я заметил, что это все еще неправильно: 10 означает 10 мс, но я получаю «всего» 83 кадра в секунду вместо 100. На 1 мс я получаю 850 кадров в секунду. Таким образом, разница в том, какой fps я получаю, и то, что я должен получить, довольно стабильна. Мне кажется, что что-то не так со сроками?

Кто-нибудь знает, в чем может быть проблема, и / или есть предложения по получению стабильных 60 кадров в секунду?

Спасибо!


person Mee    schedule 07.10.2010    source источник
comment
Произойдет ли это, если вы создадите новый пустой проект XNA? (Просто пустой синий экран.) Если нет, не могли бы вы опубликовать какой-нибудь код, который работает медленно?   -  person Andrew Russell    schedule 08.10.2010
comment
Кроме того, небольшое собственное тестирование - я обнаружил, что получаю 50 кадров в секунду, если мое приложение не фокусируется. Если есть фокус, я получаю 60.   -  person Andrew Russell    schedule 08.10.2010
comment
Так же бывает с пустым / синим экраном. И я не думаю, что смогу уделять этому больше внимания :).   -  person Mee    schedule 14.10.2010
comment
Еще немного кода поможет определить, в чем проблема   -  person Neil Knight    schedule 29.10.2010


Ответы (2)


Разве не возможно, что FRAPS не дает вам точных результатов? Вы пробовали добавить в игру свой собственный счетчик частоты кадров и посмотреть, что говорят эти результаты? У Шона Харгривза есть метод, который он закодировал в своем блоге, и его не составит труда добавить в новый пустой игровой проект XNA.

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

Вы видите один и тот же FPS или сообщаете по-другому, когда вычисляете самостоятельно?

person George Clingerman    schedule 12.01.2011

Я собрал следующий код на XNA 4, и он получает заблокированные 60 кадров в секунду. Попробуйте это в своей системе (вам просто нужно добавить соответствующий спрайт-шрифт) и посмотрите, получите ли вы тоже 60 кадров в секунду. Если да, внесите изменения в код проблемы и посмотрите, получите ли вы тот же результат.

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);
    }
}
}
person Dracorat    schedule 25.10.2011