I'm using DirectX 11. For simplicity, and to reproduce the problem, I narrowed it down to the following steps:
Replace the Sample3DSceneRenderer::Update method with the following code:
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);
}
}
Add the following function to trace the values in the Output window:
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
}
When I run the app, the Output window shows the following values:
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.
Question: Why does the TotalSeconds values increase and then decrease and then increase again etc.? For example: 0.01, 0.02, 0.00, 0.01. Shouldn't they always increase?
The bug is in App::OnLaunched. The version in the template is creating two DirectXPage
s:
m_directXPage = ref new DirectXPage();
rootFrame->Navigate(TypeName(DirectXPage::typeid), e->Arguments);
I have a modified version that only creates a single version by taking a reference to the one created during navigation, but I haven't spent much time checking on error cases.
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();
}