0

I'm trying to define a time step for the physics simulation in a PhysX application, such that the physics will run at the same speed on all machines. I wish for the physics to update at 60FPS, so each update should have a delta time of 1/60th of a second.

My application must use GLUT. Currently, my loop is set up as follows.

Idle Function:

void GLUTGame::Idle()
{
    newElapsedTime = glutGet(GLUT_ELAPSED_TIME);
    deltaTime = newElapsedTime - lastElapsedTime;
    lastElapsedTime = newElapsedTime;

    glutPostRedisplay();
}

The frame rate does not really matter in this case - it's only the speed at which my physics update that actually matters.

My render function contains the following:

void GLUTGame::Render()
{
    // Rendering Code

    simTimer += deltaTime;

    if (simTimer > m_fps)
    {
        m_scene->UpdatePhys(m_fps);
        simTimer = 0;
    }
}

Where:

Fl32 m_fps = 1.f/60.f

However, this results in some very slow updates, due to the fact that deltaTime appears to equal 0 on most loops (which shouldn't actually be possible...) I've tried moving my deltaTime calculations to the bottom of my rendering function, as I thought that maybe the idle callback was called too often, but this did not solve the issue. Any ideas what I'm doing wrong here?

4

3 に答える 3

2

OpenGL Web サイトから、渡されたミリ秒数をintglutGet(GLUT_ELAPSED_TIME)として返すことがわかりました。したがって、メソッドを 1 秒あたり約 2000 回呼び出すと、そのような呼び出しの後に経過する時間は約 1000 * 1/2000 = 0.5 ミリ秒になります。したがって、1 秒あたり 2000 回を超える void の呼び出しでは、整数の丸めにより0が返されます。void GLUTGame::Idle()GLUTGame::Idle()glutGet(GLUT_ELAPSED_TIME)

于 2014-01-07T15:33:52.157 に答える
0

非常に小さな数値を大きな数値に加算すると、丸め誤差が発生する可能性があります。これを試して:

void GLUTGame::Idle()
{
  newElapsedTime = glutGet(GLUT_ELAPSED_TIME);
  timeDelta = newElapsedTime - lastElapsedTime;
  if (timeDelta <  m_fps) return;
  lastElapsedTime = newElapsedTime;

  glutPostRedisplay();
}

必要に応じて、他の方法で同様のことを行うことができます。

于 2014-01-07T15:14:23.157 に答える
0

GLUT や PhysX については何も知りませんが、ゲームの実行速度に関係なく (整数を使用して) 同じレートで何かを実行する方法を次に示します。

if (currentTime - lastUpdateTime > msPerUpdate)
{
    DWORD msPassed = currentTime - lastUpdateTime;
    int updatesPassed = msPassed / msPerUpdate;
    for (int i=0; i<updatesPassed; i++)
        UpdatePhysX(); //or whatever function you use
    lastUpdateTime = currentTime - msPassed + (updatesPassed * msPerUpdate);
}

はゲーム ループを実行currentTimeするたびに更新され、 は PhysX が最後に更新された時刻であり、は各更新に割り当てたミリ秒数 (60 fps の場合は 16 または 17 ミリ秒) です。timeGetTimelastUpdateTimemsPerUpdate

浮動小数点の更新係数をサポートしたい場合 (物理アプリケーションに推奨されます)、次のようにフレームごとに定義しfloat timeMultiplierて更新します。これを行うには、すべての更新要因を乗算するパラメーターを取得して更新する必要があります。timeMultiplier = (float)frameRate / desiredFrameRate;frameRatedesiredFramerateUpdatePhysXfloat

于 2014-01-07T17:08:10.837 に答える