OpenGL: перемещение по 3D-сцене

Я пытаюсь перемещать автомобиль по сцене с помощью клавиш со стрелками. Я могу вращать транспортное средство вокруг себя, используя клавиши влево/вправо, но когда я пытаюсь двигаться вперед/назад, оно следует только одной оси, независимо от того, в какую сторону обращено лицо транспортного средства.

glPushMatrix();

    // movement
    glTranslatef(movement, 0.0, 0.0);

    // turning
    glTranslatef(base, 0.0, 0.0);
    glRotatef(turnAngle, 0.0, 1.0, 0.0);
    glTranslatef(-base, 0.0, 0.0);

    drawCar();

glPopMatrix();

На данный момент я только увеличиваю или уменьшаю movement на клавишах вверх/вниз. Насколько я понимаю, причина, по которой мой объект перемещается по одной оси, заключается в том, что я перевожу только на movement по оси x. Как отследить, куда обращена передняя часть моего автомобиля при повороте, и двигаться «вперед» в этом направлении?


person rafvasq    schedule 03.12.2017    source источник
comment
Возможный дубликат OpenGL — вращение не работает   -  person Spektre    schedule 03.12.2017


Ответы (1)


Прежде всего, вы должны знать, что вы используете старый и устаревший способ работы в OpenGL. См. Khronos wiki — Конвейер фиксированных функций и см. Вики Khronos — Legacy OpenGL.


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

Для контролируемого перемещения объекта по сцене необходимо постепенно изменять матрицу модели. Это означает, что вы должны рассчитать текущее движение и текущую матрицу вращения. Примените движение и вращение к модели и сохраните модель для следующего цикла цикла. В следующем цикле цикла вы должны использовать матрицу управляемой модели из предыдущего цикла, и вы должны применить новое движение и вращение. Это приводит к инкрементным изменениям модели, всегда основанным на ее текущем положении и ориентации.

введите здесь описание изображения

Для постепенного изменения матрицы модели необходимо сделать следующее:

  • Инициализируйте матрицу модели с начальным положением объекта
  • Загрузите матрицу текущей модели glLoadMatrixf
  • Примените новый перевод и поворот с помощью glTranslatef. и glRotatef
  • Сохраните матрицу модели для следующего цикла glGetFloatv(GL_MODELVIEW_MATRIX, view_mat)

В OpenGL существует один матричный стек для каждого матричного режима (см. glMatrixMode). Режимы матрицы: GL_MODELVIEW, GL_PROJECTION и GL_TEXTURE.
Для матрицы модели вам нужна переменная, в которой вы можете ее сохранить. model_mat должен быть инициализирован начальной позицией, текущую матрицу стека матриц можно получить с помощью glGetFloatv(GL_MODELVIEW_MATRIX, model_mat):

float model_mat[16];

glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glTranslatef(base, 0.0, 0.0);
glGetFloatv(GL_MODELVIEW_MATRIX, model_mat);
glPopMatrix();

Пошаговое изменение матрицы модели можно обработать следующим образом:

float add_movment   = ....; 
flaot add_turnangle = ....;

glMatrixMode(GL_MODELVIEW);
glPushMatrix();

// load the current position and orientation of the object
glLoadMatrixf(model_mat);

// add movment
glTranslatef(add_movment, 0.0, 0.0);

// add trun angle
glRotatef(add_turnangle, 0.0, 1.0, 0.0);

// get the new model matrix
glGetFloatv(GL_MODELVIEW_MATRIX, model_mat);

// draw the object
drawCar();

glPopMatrix();
person Rabbid76    schedule 03.12.2017