StepTimer.GetTotalSeconds()产生的值并不总是增加

时间:2017-09-19 23:25:33

标签: c++ timer directx-11

我正在使用DirectX 11.为了简单起见并重现问题,我将其缩小到以下步骤:

  1. 在Visual Studio中创建一个新的“DirectX和XAML应用程序(UWP)”(我正在使用VS 2017)。
  2. 使用以下代码替换Sample3DSceneRenderer :: Update方法:

    void Sample3DSceneRenderer::Update(DX::StepTimer const& timer)
    {
        if (!m_tracking)
        {
            double total = timer.GetTotalSeconds();
    
            // Convert degrees to radians, then convert seconds to rotation angle
            float radiansPerSecond = XMConvertToRadians(m_degreesPerSecond);
            double totalRotation = total * radiansPerSecond;
            float radians = static_cast<float>(fmod(totalRotation, XM_2PI));
    
            DX::DebugTrace(L"num = %4.2f\t%4.2f\n", radians, total);
    
            Rotate(radians);
        }
    }
    
  3. 添加以下函数以跟踪“输出”窗口中的值:

    inline void DebugTrace(const wchar_t *format, ...)
    {
        // Generate the message string.
        va_list args;
        va_start(args, format); // initialize the argument list
        wchar_t buffer[1024];
        va_end(args);
    
        OutputDebugStringW(buffer); // this is a Windows function
    }
    
  4. 当我运行应用程序时,“输出”窗口显示以下值:

        num = 0.01  0.01
        num = 0.02  0.02
        num = 0.00  0.00 // decreased
        num = 0.00  0.01 // decreased
        num = 0.03  0.04
        num = 0.05  0.06
        num = 0.02  0.02 // decreased
        num = 0.06  0.07
        num = 0.03  0.04 // decreased
        num = 0.07  0.09
        num = 0.04  0.06 // decreased
        num = 0.08  0.11
        num = 0.06  0.07 // decreased
        num = 0.10  0.12 
        num = 0.07  0.09 // decreased
        num = 0.11  0.14
        num = 0.08  0.11 // decreased
        num = 0.12  0.16
        num = 0.10  0.12 // decreased
        num = 0.11  0.14 
        num = 0.14  0.17
        num = 0.12  0.16 // decreased
        num = 0.15  0.19
        num = 0.16  0.21
        num = 0.14  0.17 // decreased
        num = 0.18  0.22
        num = 0.15  0.19 // decreased
        num = 0.16  0.21 
        num = 0.19  0.24
        num = 0.20  0.26
        num = 0.18  0.22 // decreased
        etc.
    

    问题:为什么TotalSeconds值会增加然后减少然后再增加等等?例如:0.01,0.02,0.00,0.01。它们不应该总是增加吗?

1 个答案:

答案 0 :(得分:1)

该错误发生在App :: OnLaunched中。模板中的版本创建了两个DirectXPage s:

  • 直接分配:m_directXPage = ref new DirectXPage();
  • 导航:rootFrame->Navigate(TypeName(DirectXPage::typeid), e->Arguments);

我有一个修改后的版本,只通过引用导航期间创建的版本来创建单个版本,但我没有花太多时间检查错误情况。

void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e)
{
#if _DEBUG
       if (IsDebuggerPresent())
       {
              DebugSettings->EnableFrameRateCounter = true;
       }
#endif

       auto rootFrame = dynamic_cast<Frame^>(Window::Current->Content);

       // Do not repeat app initialization when the Window already has content,
       // just ensure that the window is active
       if (rootFrame == nullptr)
       {
              // Create a Frame to act as the navigation context and associate it with
              // a SuspensionManager key
              rootFrame = ref new Frame();

              rootFrame->NavigationFailed += ref new Windows::UI::Xaml::Navigation::NavigationFailedEventHandler(this, &App::OnNavigationFailed);

              // Place the frame in the current Window
              Window::Current->Content = rootFrame;
       }

       if (rootFrame->Content == nullptr)
       {
              // When the navigation stack isn't restored navigate to the first page,
              // configuring the new page by passing required information as a navigation
              // parameter
              rootFrame->Navigate(TypeName(DirectXPage::typeid), e->Arguments);
       }

       if (m_directXPage == nullptr)
       {
              m_directXPage = dynamic_cast<DirectXPage^>(rootFrame->Content);
       }

       if (e->PreviousExecutionState == ApplicationExecutionState::Terminated)
       {
              m_directXPage->LoadInternalState(ApplicationData::Current->LocalSettings->Values);
       }

       // Ensure the current window is active
       Window::Current->Activate();
}