Обновление кадра, скорость и время (Vulkan + WinApi)

248
28 марта 2018, 06:02

Здравствуйте. Пытаюсь разобраться в Vulkan, но вопрос скорее даже не по нему. В общем дошел до стадии описания перемещений камеры в пространстве когда зажаты какие-либо кнопки на клавиатуре (по задумке WASD). Набросал небольшую структуру описывающую положение камеры, вот она:

struct{
    struct { float x = 0.0f; float y = 0.0f; float z = 0.0f; } position;
    struct { float x = 0.0f; float y = 0.0f; float z = 0.0f; } rotation;
    struct { int x = 0; int y = 0; int z = 0; } movement;
    float movementSpeed = 0.1f;
    bool IsMoving() const {
        return this->movement.x != 0 || this->movement.y != 0 || this->movement.z != 0;
    };
} camera;

Переменная movement, в этой структуре, по сути отвечает за направление (1 - положительное, -1 - отрицательное, 0 - не двигается по данной оси). Эта переменная меняется при нажатии и отпускании клавиш (в оконной процедуре).

Затем я подумал, что если в цикле просто увеличивать значения позиций по разным осям на определенную величину, то в итоге движение будет происходить быстрее на более быстрых компьютерах (где цикл работает быстрее), и медленнее на слабых. Поэтому я решил что нужно привязаться ко времени. Создал в начале программы переменную содержащую время последнего кадра

// Время последнего кадра (точнее последней итерации цикла)
time_point<high_resolution_clock> lastFrameTime;

А затем в самом цикле я делаю примерно следующее

    // Сколько наносекунд прошло с последней итерации
    int64_t delta = std::chrono::duration_cast<std::chrono::nanoseconds>(high_resolution_clock::now() - lastFrameTime).count();
    // Сколько прошло миллисекунд
    float deltaMs = (float)delta / 1000000;
    // Если камера движется (какая-то из кнопок зажата)
    // следует обновить ее положение
    if (camera.IsMoving()) {
        camera.position.x += ((float)camera.movement.x * (camera.movementSpeed * deltaMs));
        camera.position.y += ((float)camera.movement.y * (camera.movementSpeed * deltaMs));
        camera.position.z += ((float)camera.movement.z * (camera.movementSpeed * deltaMs));
    }
    // Обновить рендерер и отрисовать кадр
    vkRenderer->SetCameraPosition(camera.position.x, camera.position.y, camera.position.z);
    vkRenderer->Update();
    vkRenderer->Draw();
    // Обновить время последнего кадра
    lastFrameTime = high_resolution_clock::now();

То есть я получаю время, которое прошло с последнего кадра, и умножаю на него скорость, чтобы получить необходимый путь, который нужно прирастить к положению за кадр (банальное s=vt).

Казалось бы все должно быть хорошо, но нет!

Когда я делаю так, как описал выше, камера двигается резкими рывками. То есть не плавно, будто время итерации всякий раз сильно варьируется (кстати это правда так! Я выводил это время в консоль, и оно правда иногда по каким-то причинам слишком велико. В основном это 250-300 наносекунд, но иногда доходит до нескольких тысяч). Но когда я вместо deltaMs, при вычислении позиции, использую какую-то константную величину - все начинает двигаться плавно, что вообще странно (ведь если время цикла такое переменчивое, то в тот момент когда он подтормаживает, камера должна двигаться вроде как медленнее)

И собственно вопрос - где и что я не так делаю? Почему программа ведет себя так странно? Может я не учитываю каких-то мелочей, которые происходят неявно при работе с этими таймерами? Или может быть я в корне не верно рассуждаю? За ранее благодарю за ответы.

READ ALSO
Не читается слово из заданного файла

Не читается слово из заданного файла

Не читает слова из файла "inputtxt" (24 строчка)

252
Мультипликативное хеширование

Мультипликативное хеширование

Занимался созданием хеш-таблицы, где необходимо было использовать мультипликативное хешированиеПодскажите пожалуйста правильно ли я его...

251
Упростить написание кода макросом

Упростить написание кода макросом

Имеется множество примерно таких методов:

262
Зашифровать файл и разшифровать

Зашифровать файл и разшифровать

При расшифровке в конце файла появляются лишние символыС чем это связано?

288