我正确计算我的FPS吗?

时间:2011-04-10 19:02:28

标签: c++ sdl frame-rate

所以我想知道我是否正确计算了我的FPS:

Uint32 delayFrom(float startTime, float endTime){
    return(endTime - startTime );
}


int main(){
    int numFrames = 0;
    Uint32 startTime = SDL_GetTicks();
    while(!done){
        frameTime = 0;
        float fps = ( numFrames/(float)(SDL_GetTicks() - startTime) )*1000;
        cout << fps << endl;
        SDL_Delay(delayFrom(frameTime, 1/60));
        ++numFrames;
    }
}

4 个答案:

答案 0 :(得分:6)

int main() {
  int numFrames = 0;
  Uint32 startTime = SDL_GetTicks();
  while (!done) {
    ++numFrames;
    Uint32 elapsedMS = SDL_GetTicks() - startTime; // Time since start of loop
    if (elapsedMS) { // Skip this the first frame
      double elapsedSeconds = elapsedMS / 1000.0; // Convert to seconds
      double fps = numFrames / elapsedSeconds; // FPS is Frames / Seconds
      cout << fps << endl; 
    }
    SDL_Delay(1.0/60.0); // Use floating point division, not integer
  }
}

答案 1 :(得分:1)

使用FPS计数器并发限制队列的实现:

template<typename T, typename Container=std::deque<T>, typename Compare = std::less<typename Container::value_type>>
class ConcurentLimitedQueue : protected std::priority_queue<T, Container, Compare> {
  using clock_t = std::chrono::system_clock;
  using timepoin_t = std::chrono::time_point<clock_t>;
  using duration_t = std::chrono::milliseconds;

 private:
  const double ALPHA = 0.1;
 public:
  explicit ConcurentLimitedQueue(size_t upperLimit, size_t lowerLimit = 0) : upperLimit_{upperLimit},
                                                                             lowerLimit_{lowerLimit},
                                                                             stop_{false},
                                                                             lastTime_{clock_t::now()},
                                                                             counter_{0},
                                                                             fps_{0.0} {}

  bool enqueue(const T &entry) {
    std::unique_lock<std::mutex> lock(mutex_);
    while (!stop_ && std::priority_queue<T, Container, Compare>::size() >= upperLimit_) {
      removedItemCondition_.wait(lock);
    }
    if (stop_) {
      return false;
    }
    std::priority_queue<T, Container, Compare>::emplace(entry);
    updateFPS();
    newItemCondition_.notify_one();
    return true;
  }

  bool enqueue(T &&item) {
    std::unique_lock<std::mutex> lock(mutex_);
    while (!stop_ && this->c.size() >= upperLimit_) {
      removedItemCondition_.wait(lock);
    }
    if (stop_) {
      return false;
    }
    std::priority_queue<T, Container, Compare>::emplace(std::move(item));
    updateFPS();
    newItemCondition_.notify_one();
    return true;
  }

  bool dequeue(T &item) {
    std::unique_lock<std::mutex> lock(mutex_);
    while (!stop_ && std::priority_queue<T, Container, Compare>::size() <= lowerLimit_) {
      newItemCondition_.wait(lock);
    }
    if (stop_) {
      return false;
    }
    item = std::priority_queue<T, Container, Compare>::top();
    std::priority_queue<T, Container, Compare>::pop();
    removedItemCondition_.notify_one();
    return true;
  }

  T dequeue() {
    std::unique_lock<std::mutex> lock(mutex_);
    while (!stop_ && std::priority_queue<T, Container, Compare>::size() <= lowerLimit_) {
      newItemCondition_.wait(lock);
    }
    if (stop_) {
      return {};
    }
    auto item{std::priority_queue<T, Container, Compare>::top()};
    std::priority_queue<T, Container, Compare>::pop();
    removedItemCondition_.notify_one();
    return item;
  }

  T top() {
    std::unique_lock<std::mutex> lock(mutex_);
    while (!stop_ && std::priority_queue<T, Container, Compare>::empty()) {
      newItemCondition_.wait(lock);
    }
    if (stop_) {
      return {};
    }
    return std::priority_queue<T, Container, Compare>::top();
  }

  float fps() {
    return static_cast<float>(fps_);
  }

  void stop() {
    std::unique_lock<std::mutex> lock(mutex_);
    stop_ = true;
    newItemCondition_.notify_all();
    removedItemCondition_.notify_all();
  }

  void clear() {
    std::unique_lock<std::mutex> lock(mutex_);
    while (!std::priority_queue<T, Container, Compare>::empty()) {
      std::priority_queue<T, Container, Compare>::pop();
    }
    stop_ = false;
    counter_ = 0;
    fps_ = 0.0;
  }

  bool empty() {
    std::unique_lock<std::mutex> lock(mutex_);
    return std::priority_queue<T, Container, Compare>::empty();
  }

 protected:
  void updateFPS() {
    counter_++;
    const auto now{clock_t::now()};
    const auto delta{now - lastTime_};
    if (counter_ && delta > duration_t(1000)) {
      const double fps{(1000.0 * counter_) / std::chrono::duration_cast<duration_t>(delta).count()};
      fps_ = (ALPHA * fps) + (1.0 - ALPHA) * fps_;
      counter_ = 0;
      lastTime_ = now;
    }
  }

 private:
  size_t upperLimit_;
  size_t lowerLimit_;
  std::atomic_bool stop_;
  timepoin_t lastTime_;
  size_t counter_;
  std::atomic<double> fps_;
  std::mutex mutex_;
  std::condition_variable newItemCondition_;
  std::condition_variable removedItemCondition_;
};

答案 2 :(得分:0)

frameTime永远不会被赋予除0以外的任何东西。大概这是一个错误。

答案 3 :(得分:0)

cout可能会很慢,因此要获得更精确的值,您需要将时间测量值和输出值分开。

int main(){
    int numFrames = 0;    
    long totalTime = 0;
    while(!done){
        // measure time
        const Uint32 startTime = SDL_GetTicks();
        SDL_Delay( 1.0f/60.0f );
        const Uint32 endTime = SDL_GetTicks();

        // calculate result
        totalTime += endTime - startTime;
        ++numFrames;
        float fps = numFrames / (totalTime / 1000.0);
        cout << fps << endl;
    }
}