Вращение камеры, используемой для перспективной проекции - PullRequest
0 голосов
/ 22 декабря 2009

Я только начал играть с OpenGl, чтобы визуализировать несколько структур, каждая из которых состоит из многоугольника. По сути, я хочу выполнить эквивалент установки камеры в точке (0,0, z) в мировых (структурных) координатах и ​​повернуть ее вокруг осей x, y и z мировых осей (в этом порядке!) Для рендеринга. вид каждой структуры (насколько я понимаю, обычно используется обратная матрица камеры). Таким образом, насколько я понимаю, мне нужно перевести (в мировое происхождение, т.е. (0,0, -z)) * rotateZ rotateY rotateX * translate (переопределить мировое происхождение см. Ниже)

Так что я думаю, что мне нужно что-то вроде:

//Called when the window is resized
void handleResize(int w, int h) {
    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(9.148, (double)w / (double)h, 800.0, 1500.0);
}

float _Zangle = 10.0f; 
float _cameraAngle = 90.0f;

//Draws the 3D scene
void drawScene() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
    glLoadIdentity(); //Reset the drawing perspective

    glTranslatef(0.0f, 0.0f, -z); //Move forward Z (mm) units
    glRotatef(-_Zangle, 0.0f, 0.0f, 1.0f); //Rotate "camera" about the z-axis
    glRotatef(-_cameraAngle, 0.0f, 1.0f, 0.0f); //Rotate the "camera" by camera_angle about y-axis
    glRotatef (90.0f,1.0f,0.0f,0.0f); // rotate "camera" by 90 degrees about x-axis
    glTranslatef(-11.0f,189.0f,51.0f); //re-define origin of world coordinates to be (11,-189,-51) - applied to all polygon vertices

glPushMatrix(); //Save the transformations performed thus far

glBegin(GL_POLYGON);


    glVertex3f(4.91892,-225.978,-50.0009);
        glVertex3f(5.73534,-225.978,-50.0009);
        glVertex3f(6.55174,-225.978,-50.0009);
        glVertex3f(7.36816,-225.978,-50.0009);
        .......// etc
glEnd();
glPopMatrix();

Однако, когда я компилирую и запускаю это, _angle и _cameraAngle, кажется, перевернуты, т.е. _angle, кажется, вращается вокруг оси y (по вертикали) Viewport и _cameraAngle вокруг оси z (в плоскость Viewport)? Что я делаю не так?

Спасибо, что нашли время, чтобы прочитать это

Ответы [ 5 ]

5 голосов
/ 22 декабря 2009

Краткий ответ: используйте gluLookAt (). Эта служебная функция создает правильную матрицу просмотра.

Более длинный ответ заключается в том, что каждый вызов преобразования OpenGL берет текущую матрицу и умножает ее на матрицу, созданную для выполнения преобразования. Вызывая серию функций преобразования OpenGL, вы строите одну матрицу преобразования, которая будет применять комбинацию преобразований. По сути, матрица будет M = M1 * M2 * M3. , , Математически преобразования применяются справа налево в приведенном выше уравнении.

Ваш код не двигает камеру. Он остается в начале координат и смотрит вниз по отрицательной оси Z. Ваши преобразования перемещают все в пространстве модели в (11, -189, -51), поворачивают все на 90 градусов вокруг оси x, поворачивают все на 90 градусов вокруг оси y, поворачивают все на 10 градусов вокруг оси z, а затем переводят все -z вдоль оси Z.

РЕДАКТИРОВАТЬ: Больше информации

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

В такой ситуации я обычно слежу за положением камеры, используя долготу, широту и высоту с центром в начале координат. Вычисление x, y, z для координат глаза просто x = elv * cos (lat) * sin (lon), y = elv * sin (lat), z = elv * cos (lat) * cos (lat).

Мой вызов gluLookAt будет gluLookAt(x, y, z, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

Вы можете повернуть камеру вверх, изменив последние три координаты для gluLookAt. * ​​1017 *

1 голос
/ 22 декабря 2009

Ось Z идет от центра монитора к вам. Таким образом, вращение вокруг оси z должно заставить камеру вращаться на месте (как 2D-вращение только на плоскости xy). Я не могу сказать, но это то, что здесь происходит?

0 голосов
/ 22 декабря 2009

Я думаю, вы смешиваете оси своего мира с осями камеры,

GLRotatef использует только оси камеры, они не совпадают с вашими мировыми осями после вращения камеры.

0 голосов
/ 22 декабря 2009

Краткий ответ: Хороший совет

Более длинный ответ: Да, порядок умножения матриц ясен ... это то, что я имел в виду под обратной матрицей камеры, чтобы показать перемещение всех мировых координат структур в координаты камеры (отсюда и использование «камеры» в моих комментариях; -)) вместо фактического перевода и поворота камеры в мировые координаты.

Так что, если я правильно читаю между строк, вы предлагаете что-то вроде:

void drawScene() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
    glLoadIdentity(); //Reset the drawing perspective
gluLookAt(0.0,0.0,z,11.0,-189.0,-51.0,0.0,1.0,0.0); //eye(0,0,z) look at re-defined world origin(11,-189,-51) and up(0.0,1.0,0.0)

    glRotatef(-_Zangle, 0.0f, 0.0f, 1.0f); //Rotate "camera" (actually structures) about the z-axis
    glRotatef(-_cameraAngle, 0.0f, 1.0f, 0.0f); //Rotate the "camera" (actually structures!) by camera_angle about y-axis
    glRotatef (90.0f,1.0f,0.0f,0.0f); // rotate "camera" (actually structures) by 90 degrees about x-axis


glPushMatrix();

Или я все еще что-то упускаю?

0 голосов
/ 22 декабря 2009

Возможно, вы столкнулись с Подвесом на подвесе . Попробуйте удалить одно из вращений и посмотрите, все ли работает так, как должно.

Хотя на самом деле вы не можете перемещать камеру в OpenGL, вы можете имитировать движение камеры, перемещая все остальное. Вот почему вы слышите об обратной матрице камеры. Вместо перемещения камеры на (0, 0, 10) мы можем переместить все в мире на (0, 0, -10). Если вы разложите их в матрицы, вы обнаружите, что они противоположны друг другу.

Я также заметил, что, учитывая представленный код, вам не нужны вызовы glPushMatrix() / glPopMatrix(). Возможно, есть код, который вы не показали, который требует их.

Наконец, можете ли вы дать представление о том, что именно вы пытаетесь визуализировать? Отладка вращений может быть сложной без некоторого контекста.

...