Возникла небольшая проблема с перемещением камеры в зависимости от времени, проведенного с использованием GLUT / OpenGL - PullRequest
1 голос
/ 10 апреля 2011

Прежде чем кто-либо спросит, это для университетского проекта, и Я должен использовать GLUT .Я не отмечаю это как домашнее задание, потому что это не является обязательным требованием, и при этом у меня не будет дополнительных очков за это.

С GLUT, для незнакомых людей, у вас есть:

  • glutIdleFunc(func): регистрирует функцию рендеринга, и это означает, что когда GLUT больше ничего не делает, она вызовет эту функцию.Другими словами, он будет продолжать рендеринг как можно быстрее.
  • glutTimerFunc(msecs, func, val): регистрирует функцию, которая будет вызываться в msecs, и рекурсивная регистрация той же самой функции обеспечит движение с фиксированным временем.

Теперь я стараюсь избегать этих функций для этой цели и в большинстве обсуждений / статей, которые я нашел о GLUT, использую их для движения по времени.Итак, я пришел сюда еще раз ... Но если я не использую какие-либо из этих функций, как отображаются кадры?Я просто называю glutPostRedisplay, и будет отрисован один кадр.

Мне удалось реализовать перемещение по времени в GLUT простым способом.Может быть не самая лучшая реализация, но она не слишком сложна и работает.Ну, есть только небольшая проблема, поэтому я здесь.

Движение моей камеры основано на втором законе движения Ньютона, где я вычисляю движение смещения следующим образом:

Vector3D displacement = (CurrentVelocity * elapsedTime) +
    (Acceleration * 0.5f * elapsedTime * elapsedTime);

* * * * elapsedTime происходит от моей реализации таймера, и я думаю, что в этом проблема.Проблема в том, что displacement должно быть положительным или отрицательным в зависимости от направления движения, но если CurrentVelocity является действительно низким значением (то есть: -0.1f), displacement будет положительным, когда оно должно быть отрицательным.Остальная часть кода будет ускорять или замедлять камеру, поэтому проблема возникает только при ускорении, потому что именно тогда CurrentVelocity будет небольшим, и в результате камера немного сместится вправо (положительно), а затем влево (отрицательно)) когда он набирает достаточный импульс, чтобы дать отрицательное значение displacement.

Теперь, когда на сцене нет движения, ничто не отображается вообще.Когда я нажимаю на клавиши перемещения, я делаю это:

CameraDirection.z = CAMERA_WALK_BACKWARD;
SceneTimer.PostRedisplayWindow();

Это также происходит из моего класса таймера, я делаю это вместо вызова glutPostRedisplay, и причина этого заключается в следующем:

void Timer::PostRedisplayWindow(void) {
    currentTime = glutGet(GLUT_ELAPSED_TIME);
    glutPostRedisplay();
}

Мне нужно получить currentTime (который станет previousTime, когда мне нужно рассчитать истекшее время), а затем я позвоню glutPostRedisplay.Будет визуализирован один кадр, что означает, что будет вызываться renderScene:

void renderScene(void) {
    (...)

    glLoadIdentity();

    elapsedTime = SceneTimer.GetElapsedTimeInSeconds();

    SceneCamera.Move(CameraDirection, elapsedTime);
    SceneCamera.LookAt();

    drawCompleteScene();

    glutSwapBuffers();

    checkAnimationRedisplay();
}

Как видите, истекшее время рассчитывается, и камера перемещается по нему.Все в сцене прорисовано, поменяйте местами буферы, и тогда у меня будет эта дополнительная функция, которая будет проверять, нужно ли что-то анимировать, в этом случае камера требует:

void checkAnimationRedisplay(void) {
    if(SceneCamera.IsCameraMoving()) {
        glutPostRedisplay();
        return;
    }
}

Она будет продолжать вызывать glutPostRedisplayпока камера не перестанет двигаться.Это означает, что renderScene будет вызываться каждый раз, истекшее время вычисляется, и камера перемещается в зависимости от времени, все работает;кроме того, конечно, уже упомянутый маленький глюк, но только тот, который заставил меня создать этот длинный вопрос (извините за это).

Все, чего не хватает, - это самая важная функция этого вопроса, которая вычисляетистекшее время, простое как это:

float Timer :: GetElapsedTimeInSeconds (void) {static int previousTime = 0;static int elapsedTime = 0;

previousTime = currentTime;
currentTime = glutGet(GLUT_ELAPSED_TIME);
elapsedTime = currentTime - previousTime;

return elapsedTime / 1000.0f;

}

Возможно, что-то не так с моим кодом таймера, верно?Я имею в виду, двигаясь вперед или вправо (положительные значения), проблем нет.Движение плавное и основанное на времени.Например, если я установлю скорость движения 5 м / с, на самом деле потребуется 25 секунд для перемещения на 25 метров (я предполагаю, что 1 м = 1,0f).

Итак, что я делаю неправильно стаймер, чтобы отрицательные значения начали двигаться вправо на долю секунды и только затем влево, как и должно быть?

1 Ответ

0 голосов
/ 12 апреля 2011

Один ответ, который решает мою проблему, можно найти здесь: https://gamedev.stackexchange.com/questions/10902/having-a-slight-problem-moving-my-camera-based-on-time-passed-using-glut-opengl

...