【问题标题】:SDL_GetTicks() accuracy below the millisecond levelSDL_GetTicks() 精度低于毫秒级
【发布时间】:2014-10-18 14:33:38
【问题描述】:

我目前使用 SDL2 进行编程。 一切正常,但SDL_GetTicks() 方法有问题。 通常它应该返回以毫秒为单位的总应用时间,但它总是在大部分时间返回值 0,有时返回值 1。

我使用 SDL_INIT_EVERYTHING 标志初始化了 SDL。

以下代码的问题是循环太快,所以增量时间小于1毫秒。有没有办法达到更高的精度?

#include "Application.hpp"

void Application::Initialize()
{
    int sdl_initialize_result = SDL_Init(SDL_INIT_EVERYTHING);
    if(sdl_initialize_result < 0)
    {
        std::cerr << "Failed to initialize SDL !" << std::endl << SDL_GetError() << std::endl;
    }

    window = SDL_CreateWindow("Project Unknown", 100, 100, 800, 600, SDL_WINDOW_SHOWN);
    if(window == nullptr)
    {
        std::cerr << "Failed to create  SDL window !" << std::endl << SDL_GetError() << std::endl;
    }

    last_update_time = SDL_GetTicks();
}

void Application::Dispose()
{
    SDL_DestroyWindow(window);
    SDL_Quit();
}

void Application::Render()
{
}

void Application::Update()
{
    Uint32  current_time = SDL_GetTicks();
    Uint32  delta_time = current_time - last_update_time;


    SDL_Event event;
    while(SDL_PollEvent(&event))
    {
        switch(event.type)
        {
            case SDL_QUIT:
            {
                should_close = true;
            }
            break;

            default:
            {

            }
            break;
        }
    }

    // Update game objects with delta_time

    last_update_time = current_time;
}


void Application::Run()
{
    Initialize();

    should_close = false;
    do
    {
        Render();
        Update();
    }
    while(should_close == false);

    Dispose();
}

【问题讨论】:

  • 一些代码可以帮助我们解决问题。
  • 以及,哪个使用它会给您带来问题? last_update_time 是什么类型?
  • 问题是,SDL_GetTicks() 返回值是没有意义的。始终为 0,有时为 1。但在每个文档和教程中,此方法应返回自 SDL 初始化以来的毫秒数。
  • 尝试将 Uint32 更改为常规 int。仅使用 int 时对我来说效果很好。此外,如果您自己编译 SDL2,请确保当前提交中没有错误。
  • 您的问题完全具有误导性。您说问题出在SDL_GetTicks() 的返回值上,但从您的编辑中可以清楚地看出情况并非如此。您应该修改您的问题,以便解决您遇到的实际问题。

标签: c++ sdl sdl-2 timedelta


【解决方案1】:

如果您想要更高的精度,则不能使用 SDL_GetTicks(),但还有许多其他选择。如果你想独立于平台,你需要小心,但这里有一个可移植的 C++11 示例,可以帮助你入门:

#include <iostream>
#include <chrono>
typedef std::chrono::high_resolution_clock Clock;

int main()
{
    auto t1 = Clock::now();
    auto t2 = Clock::now();
    std::cout << "Delta t2-t1: " 
              << std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count()
              << " nanoseconds" << std::endl;
}

在 ideone.com 上运行它给了我:

Delta t2-t1: 282 nanoseconds

【讨论】:

  • 完全依赖于编译器和操作系统。例如,在 GCC、Windows 或 MSVC 2013 下无法工作。
  • 它不依赖于操作系统,但是你需要一个能够编译 C++11 的编译器,我猜你没有。
  • 它实际上是依赖于操作系统的,因为不同的操作系统有不同的内部计数器,有些比其他更好。目前,Windows 上的主要编译器都没有能够进行实际纳秒计时的功能计时。
  • std::chrono::high_resolution_clock 是实现定义的。坚持std::chrono::steady_clock
【解决方案2】:

当然,您实际上需要等到 >=1 毫秒后才能更新您的最后一个滴答计数

void Application::Update()
{
    Uint32  current_time = SDL_GetTicks();
    Uint32  delta_time = current_time - last_update_time;

    SDL_Event event;
    while(SDL_PollEvent(&event))
    {
        switch(event.type)
        {
            case SDL_QUIT:
            {
                should_close = true;
            }
            break;

            default:
                break;
        }
    }

    if (delta_time >= 1)
    {
        // Update game objects with delta_time

        last_update_time = current_time;
    }   
}

【讨论】:

    猜你喜欢
    • 2020-03-18
    • 1970-01-01
    • 1970-01-01
    • 2014-08-07
    • 2015-06-25
    • 1970-01-01
    • 2013-02-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多